美文网首页react-native
Promise在react-native中的使用

Promise在react-native中的使用

作者: 清汤白面 | 来源:发表于2020-03-04 11:02 被阅读0次

一.方法

Promise.resolve(value)

方法返回一个以给定值解析后的Promise 对象。如果该值为promise,返回这个promise;如果这个值是thenable(即带有"then" 方法)),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。

const textResolve = () => {
    let promise = Promise.resolve('test resolve');
    promise.then(value => {
        console.log("then ="+value);
    }).catch(error => {
        console.log("error ="+error);
    });
};

结果:

 LOG  then =test resolve

Promise.reject(value)

方法返回一个带有拒绝原因的Promise对象

const textReject = () => {
    let promise = Promise.reject('test reject');
    promise.then(value => {
        console.log('then =' + value);
    }).catch(error => {
        console.log('error =' + error);
    });
    promise.then(value => {
      console.log('then1 =' + value);
    },error => {
      console.log('error1 =' + error);
    });

    Promise.reject(new Error('test error ')).then(value => {
        console.log('resolve value ' + value);
    }, error => {
        console.log('reject value ' + error);
    });
};

结果:

 LOG  error1 =test reject
 LOG  reject value Error: test error 
 LOG  error =test reject

Promise.all(iterable)

方法返回一个 [Promise] 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果

const testMain=()=>{
   Promise.all([test1(),test2()]).then(results=>{
     console.log(results[0]);
     console.log(results[1]);
   }).catch(error=>{
     console.log("error==="+error);
   });
};

const test1=()=>{
  console.log("test1==start");
  return new Promise((resolve, reject) => {
    console.log("==========1");
      setTimeout(()=>{
        console.log("test1");
        resolve("my name is test1");
        console.log("test1==end");
      },2000);
  });
};

const test2=()=>{
  console.log("test2==start");
  return new Promise((resolve, reject) => {
    console.log("==========2");
    setTimeout(()=>{
      console.log("test2");
      resolve("my name is test2");
      console.log("test2==end");
    },2000);
  });
};

结果:


image.png

Promise.race(iterable)

方法返回一个 promise 实例,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
如同上例,吧all改成race

const testMain=()=>{
   Promise.race([test1(),test2()]).then(results=>{
    console.log(results);
   }).catch(error=>{
     console.log("error==="+error);
   });
};

结果


image.png

二.react-native中Promise实战

平常我们使用fetch请求网络是这样写的

const get = (url, success, fail) => {
    fetch(url, {
        method: 'GET',
    }).then(rsp => rsp.json())
        .then(rsp => {
            if (rsp.error) {
                fail && fail('==== fail');
            } else {
                success && success(rsp);
            }
        }).catch(error => {
        fail && fail('==== fail' + error);
    });
};

加入Promise后是这样写的

const getPromise = (url) => {
    return new Promise((resolve, reject) => {
        fetch(url, {
            method: 'GET',
        }).then(rsp => rsp.json())
            .then(rsp => {
                if (rsp.error) {
                    reject('==== fail');
                } else {
                    resolve(rsp);
                    console.log(JSON.stringify(rsp));
                }
            }).catch(error => {
            console.log('error==' + error);
            reject('==== fail' + error);
        });
    });
};

调用 都可以拿到所需要的结果

const loadData = () => {
    let url = 'http://gank.io/api/xiandu/categories';
    get(url, rsp => {
        console.log(JSON.stringify(rsp));
    }, error => {
        console.log('error==' + error);
    });

    getPromise(url).then(rsp => {
        console.log(JSON.stringify(rsp));
    }).catch(error => {
        console.log('error==' + error);
    });
};

有人回说fetch 也是promise,可以直接return回去嘛。
嗯 是可以的,但是网络请求,很多东西需要统一处理的,所以外面再加一层promise来封装好点。

这里有个问题,fetch没有自带的请求超时,这个时候,我们就可以想到Promise.race方法了。
一个网络请求的promise 一个超时的promise 谁先结束就返回谁的结果。知道怎么写了么,
看看是否一样

const timeOut = (httpPromise, time = 6000) => {

    let timeOut = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('time_out');
        }, time);
    });

    return Promise.race([httpPromise, timeOut]);
};

调用

const get = (url, success, fail) => {
    timeOut(fetch(url, {
        method: 'GET',
    }), 100)
        .then(rsp => rsp.json())
        .then(rsp => {
            if (rsp.error) {
                fail && fail('==== fail');
            } else {
                success && success(rsp);
            }
        }).catch(error => {
        fail && fail('==== fail' + error);
    });
};

const getPromise = (url) => {
    return new Promise((resolve, reject) => {
        timeOut(fetch(url, {
            method: 'GET',
        }), 600)
            .then(rsp => rsp.json())
            .then(rsp => {
                if (rsp.error) {
                    reject('==== fail');
                } else {
                    resolve(rsp);
                    console.log(JSON.stringify(rsp));
                }
            }).catch(error => {
            console.log('error==' + error);
            reject('==== fail' + error);
        });
    });
};

结果1和结果2:

 LOG  error====== failtime_out
 LOG  {"error":false,"results":[{"_id":"57c83777421aa97cbd81c74d","en_name":"wow","name":"科技资讯","rank":1},{"_id":"57c83577421aa97cb162d8b1","en_name":"apps","name":"趣味软件/游戏","rank":5},{"_id":"57a97cbd81c74b","en_name":"imrich","name":"装备党","rank":50},{"_id":"57c836b4421aa97cbd81c74c","en_name":"funny","name":"草根新闻","rank":100},{"_id":"5827dc81421aa911e32d87cc","en_name":"android","name":"","rank":300},{"_id":"582c5346421aa95002741a8e","en_name":"diediedie","name":"创业新闻","rank":340},{"_id":"5829c2bc421aa911e32d87e7","en_name":"thinking","name":"独立思想","rank":400},{"_id":"5827dd7b421b7eca","en_name":"iOS","name":"iOS","rank":500},{"_id":"5829b881421aa911dbc9156b","en_name":"teamblog","name":"团队博客","rank":600}]}
 LOG  {"error":false,"results":[{"_id":"57c83777421aa97cbd81c74d","en_name":"wow","name":"科技资讯","rank":1},{"_id":"57c83577421aa97cb162d8b1","en_name":"apps","name":"趣味软件/游戏","rank":5},{"_id":"57a97cbd81c74b","en_name":"imrich","name":"装备党","rank":50},{"_id":"57c836b4421aa97cbd81c74c","en_name":"funny","name":"草根新闻","rank":100},{"_id":"5827dc81421aa911e32d87cc","en_name":"android","name":"","rank":300},{"_id":"582c5346421aa95002741a8e","en_name":"diediedie","name":"创业新闻","rank":340},{"_id":"5829c2bc421aa911e32d87e7","en_name":"thinking","name":"独立思想","rank":400},{"_id":"5827dd7b421b7eca","en_name":"iOS","name":"iOS","rank":500},{"_id":"5829b881421aa911dbc9156b","en_name":"teamblog","name":"团队博客","rank":600}]}

当然还有更多用得到的地方,比如 AsyncStorage
我们经常用它来储取一个数据,先看看源码。如get方法,它就是callBack 和Promise一起用的。

  /**
   * Fetches an item for a `key` and invokes a callback upon completion.
   *
   * See http://facebook.github.io/react-native/docs/asyncstorage.html#getitem
   */
  getItem: function(
    key: string,
    callback?: ?(error: ?Error, result: ?string) => void,
  ): Promise {
    invariant(RCTAsyncStorage, 'RCTAsyncStorage not available');
    return new Promise((resolve, reject) => {
      RCTAsyncStorage.multiGet([key], function(errors, result) {
        // Unpack result to get value from [[key,value]]
        const value = result && result[0] && result[0][1] ? result[0][1] : null;
        const errs = convertErrors(errors);
        callback && callback(errs && errs[0], value);
        if (errs) {
          reject(errs[0]);
        } else {
          resolve(value);
        }
      });
    });
  },

我们就这样封装下

function get(name = STORAGE_KEY.Unknown) {
    return new Promise((resolve, reject) => {
        AsyncStorage.getItem(name, function (error, result) {
            if (error) {
                reject(`读取失败,读取结果为 ${error}`);
            } else {
                try {
                    let obj = JSON.parse(result);
                    if (obj !== null && typeof obj === 'object') {
                        resolve(obj);
                    } else {
                        let msg = `反序列化 AsyncStorage 失败【${name}】,读取结果为 ${result}`;
                        console.log(msg);
                        reject(msg);
                    }
                } catch (err) {
                    let msg = `反序列化 AsyncStorage 异常【${name}】,读取结果为 ${err}`;
                    console.log(msg);
                    reject(msg);
                }
            }
        });
    });
}

当然这都是部分使用,更多的请查看官方文档。

相关文章

网友评论

    本文标题:Promise在react-native中的使用

    本文链接:https://www.haomeiwen.com/subject/rdcvkhtx.html