Javascript Promise用法详解(4)
这样用起来似乎很爽,但是有个问题需要注意,我们说过每个 then() 方法都返回一个新的 Promise 对象,那既然是 Promise 对象,那肯定就有注册 onFulfilled 和 onRejected, 如果某个任务流程的 then() 方法链过长的话,前面的任务抛出异常,会导致后面的任务被跳过。
function taskA() { console.log("Task A"); throw new Error("throw Error @ Task A"); } function taskB() { console.log("Task B"); } function onRejected(error) { console.log(error); } function finalTask() { console.log("Final Task"); } var promise = Promise.resolve(); promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);
执行的结果是:
Task A
Error: throw Error @ Task A
Final Task
显然, 由于 A 任务抛出异常(执行失败),导致 .then(taskB) 被跳过,直接进入 .catch 异常处理环节。
6.1 promise chain 中如何传递参数
上面我们简单阐述了 Promise 的链式调用,能够非常有效的处理异步的流程任务。
但是在实际的使用场景中,任务之间通常都是有关联的,比如 taskB 需要依赖 taskA 的处理结果来执行,这有点类似 Linux 管道机制。 Promise 中处理这个问题也很简单,那就是在 taskA 中 return 的返回值,会在 taskB 执行时传给它。
function taskA() { console.log("Task A"); return "From Task A"; } function taskB(value) { console.log(value); console.log("Task B"); return "From Task B"; } function onRejected(error) { console.log(error); } function finalTask(value) { console.log(value); console.log("Final Task"); } var promise = Promise.resolve(); promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);
搞定,就这么简单!
6.2 resolve 和 reject 参数
reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例, 比如像上面的 getJSON() 方法一样。
var p1 = new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('fail')), 3000) }) var p2 = new Promise(function (resolve, reject) { setTimeout(() => resolve(p1), 1000) }) p2 .then(result => console.log(result)) .catch(error => console.log(error))
注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。
如果p1的状态是 pending,那么p2的回调函数就会等待p1的状态改变;
如果p1的状态已经是 resolved 或者 rejected,那么p2的回调函数将会立刻执行。
7、Promise 基本方法
ES6的Promise API提供的方法不是很多,下面介绍一下 Promise 对象常用的几个方法.