React Native开发经验集React-Native 开发阵营React Native开发

React Native学习笔记(六)

2018-03-17  本文已影响154人  于卫国

本文介绍了JavaScript中Promise以及async函数的使用。

本文首发:http://yuweiguocn.github.io/

《送友人》
青山横北郭,白水绕东城。
此地一为别,孤蓬万里征。
浮云游子意,落日故人情。
挥手自兹去,萧萧班马鸣。
—唐,李白

Promise简介

Promise 是异步编程的一种解决方案。ES6原生提供 Promise 对象。Promise 对象代表一个异步操作,有三种状态: Pending(进行中)、 Resolved(已完成,又称Fulfilled)和 Rejected(已失败)。

Promise 有两个特点:

Promise 也有一些缺点。首先,无法取消 Promise ,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数, Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

Promise简单使用

使用 new 创建一个 promise 对象,Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是resolve 函数和 reject 函数:

var promise = new Promise(function(resolve, reject) {
    // 异步处理
    var result = getAsyncResult();
    // 处理结束后、调用resolve 或 reject
    resolve(result); 
    // or reject(new Error("出错了"));
});

resolve 函数的作用是,将Promise对象的状态从Pending变为Resolved,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去; reject 函数的作用是,将Promise对象的状态从Pending变为Rejected,在异步操作失败时调用,并将异步操作报出的异常,作为参数传递出去。

Promise 实例生成以后,可以用 then 方法分别指定 Resolved 状态和 Reject 状态的回调函数。

promise.then(function(value) {
    // success
    console.log(value);
}, function(error) {
    // failure
    console.log(error);
});

then 方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是 Promise 对象的状态变为 Reject 时调用。其中,第二个函数是可选的。这两个函数都接受 Promise 对象传出的值作为参数。当不使用第二个回调函数时可以使用 catch 处理异常:

promise.then(function(value) {
    // success
    console.log(value);
}).catch(function(error) {
    // failure
    console.log(error);
});

使用 then 和 catch 处理异常的区别:

所以我们应该总是使用 catch 处理异常

Promise.resolve

静态方法 Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式。比如 Promise.resolve(42); 可以认为是以下代码的语法糖。

new Promise(function(resolve){
    resolve(42);
});

Promise.reject

Promise.reject(error) 是和 Promise.resolve(value) 类似的静态方法。比如 Promise.reject(new Error("出错了")) 就是下面代码的语法糖形式。

new Promise(function(resolve,reject){
    reject(new Error("出错了"));
});

then的链式调用

从代码上乍一看, promise.then(...).catch(...) 像是针对最初的 promise 对象进行了一连串的方法链调用。然而实际上不管是 then 还是 catch 方法调用,都返回了一个新的 promise 对象。因此可以采用链式写法,即 then 方法后面再调用另一个 then 方法。

var promise = Promise.resolve(5);
promise.then(function taskA(value){
    console.log(value);
    return Promise.resolve("taskA");
}).then(function taskB(value){
    console.log(value);
}).catch(function onRejected(error){
    console.log(error);
});

// 打印输出:
5
taskA

上面的代码使用 then 方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。每个方法中 return 的值不仅只局限于字符串或者数值类型,也可以是对象或者 promise 对象等复杂类型。return 的值会由 Promise.resolve(return的返回值); 进行相应的包装处理,因此不管回调函数中会返回一个什么样的值,最终 then 的结果都是返回一个新创建的 promise 对象。

var promise = Promise.resolve(5);
promise.then(function (value){
    return Promise.reject("error in then");
}).then(
    value => console.log(value)
).catch(
    e => console.log(e)
);

//打印输出:
error in then

前面所有 promise 对象包括一个 promise 和两个 then 产生的 promise 对象发生的异常都会被最后一个 catch 捕获。但如果前面的 promise 发生异常后,后面的 then 方法不会被调用,而是直接调用最后的 catch 方法。上述代码使用了ES6中箭头函数,使代码更简洁,不清楚的同学请移步本系列的第一篇文章。

Promise.all

Promise.all 接收一个 promise 对象的数组作为参数,数组中的 promise 将会同时执行,当这个数组里的所有 promise 对象全部变为 fulfilled 状态的时候,它才会去调用 then 方法,并且会将返回值组成一个数组传递给 then 方法。

var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = Promise.resolve(3);

Promise.all([p1,p2,p3])
.then( 
    results => console.log(results)
).catch(
    e => console.log(e)
);

//打印输出:
1,2,3

如果有变为 rejected 状态的 promise 对象,则立即会将第一个被 reject 的实例的返回值传递给 catch 方法。

var p1 = new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log("p1 execute");
        resolve(1);
    }, 100);
});
var p2 = Promise.reject("error");
var p3 = Promise.resolve(3);

Promise.all([p1,p2,p3])
.then( 
    results => console.log(results)
).catch(
    e => console.log(e)
);

//打印输出:
error
p1 execute

Promise.race

它的使用方法和 Promise.all 一样,接收一个 promise 对象数组为参数。Promise.all 在接收到的所有的对象promise都变为 FulFilled 或者 Rejected 状态之后才会继续进行后面的处理, 与之相对的是 Promise.race 只要有一个 promise 对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。

var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = Promise.resolve(3);

Promise.race([p1,p2,p3])
.then( 
    result => console.log(result)
).catch(
    e => console.log(e)
);

//打印输出:
1

async 函数

ES7提供了 async 函数,使得异步操作变得更加方便。async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。正常情况下, await 命令后面是一个 Promise 对象。如果不是,会被转成一个立即 resolve 的 Promise 对象。

function f() {
  return new Promise((resolve) => {
    setTimeout(resolve("async result"), 200);
  });
}
async function asyncHello() {
  var p = await f();
  console.log(p);
  return "async finish";
}
asyncHello().then(value => console.log(value));

//打印输出:
async result
async finish

查看React Native学习笔记相关文章

参考

上一篇 下一篇

猜你喜欢

热点阅读