Promise在react-native中的使用

一.方法

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);
                }
            }
        });
    });
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342