@yangfch3
2017-05-25T23:47:47.000000Z
字数 4029
阅读 2478
JavaScript
可以简单的认为:
立即
resolve
的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for (var i = 0; i < 10000; i++) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);
// 2 3 5 4 1
// 分析
// 2 3 5
// 本轮事件循环结束
// 4
// 本轮事件循环结束时 `.then()`
// 下一轮事件循环开始
// 1
return
之前,Promise 内的代码能一直执行两个方法返回的都是一个新的 Promise 对象,可以轻易实现 回调链。
.then()
返回一个新的 Promise 对象,该 Promise 对象的:
[[PromiseStatus]]
为 resolved
[[PromiseValue]]
为 undefined
var a = new Promise((resolve) => {resolve(1)});
var b = a.then((value) => {console.log(value + 1)})
b;
// Promise {
// [[PromiseStatus]]: "resolved",
// [[PromiseValue]]: undefined
// }
.then()
返回一个新的 Promise 对象,该 Promise 对象的:
[[PromiseStatus]]
为 resolved
[[PromiseValue]]
为 then
内回调函数返回的值
var obj = {key: 'value'};
var a = new Promise((resolve) => {resolve(1)});
var b = a.then((value) => {console.log(value + 1)})
b;
// Promise {
// [[PromiseStatus]]: "resolved",
// [[PromiseValue]]: {
// key: 'value'
// }
// }
.then()
返回值为一个 Promise 对象,该 Promise 对象即为回调函数返回的 Promise 对象。
var a = new Promise((resolve) => {resolve(1)});
var b = a.then((value) => {return new Promise((resolve, reject) => {resolve(value + 1)})});
b;
// Promise {
// [[PromiseStatus]]: "resolved",
// [[PromiseValue]]: 2
// }
Promise 错误能被 .then()
或 .catch()
处理,这两个对错误的处理类似 try...catch
的错误处理。
一个 Promise 内执行了 reject
,该 Promise 对象的状态由 pending
变为 rejected
,此时根据是否有 .then()
(第二个回调函数参数)或 .catch()
来处理这个 rejection
会有不同的表现:
.then()
(第二个回调函数参数)或 .catch()
中处理了 rejection
Uncaught (in promise)
错误rejection
都没有处理Uncaught (in promise)
错误
注意:以后如果有未处理的 rejection
会导致程序 non-zero exit
(在诸如 node server
这些运行时是致命的),所以确保 Promise 的错误有处理。
Promise 内的运行错误相当于:reject(error)
+ return
有以下几个特征:
reject(error)
并 return
(然后根据有无处理 rejection 就化归为上文相关问题)
// bbb 未定义
var a = new Promise((resolve, reject) => {
console.log(bbb);
console.log('aaa');
resolve(1);
});
// 输出
// Uncaught (in promise) ReferenceError: bbb is not defined
// at Promise (<anonymous>:1:55)
// at Promise (<anonymous>)
// at <anonymous>:1:9
a;
// 输出
// Promise {
// [[PromiseStatus]]: "rejected",
// [[PromiseValue]]: ReferenceError: bbb is not defined
// at Promise (<anonymous>:1:55)
// at Promise (<anonymous>)
// …
// }
Promise 内的运行错误相当于:reject(error)
+ return
。
特征:
resolve()
与 reject()
后的代码继续执行,直到遇到错误或 return
// bbb 未定义
var a = new Promise((resolve, reject) => {resolve(1);console.log(bbb);console.log('aaa');});
// Runtime 并没有通报 console.log(bbb) 这里的错误
a;
// 输出
// Promise {
// [[PromiseStatus]]: "resolved",
// [[PromiseValue]]: 1
// }
有以下几点需要注意:
Promise.all()
会遍历传入的可遍历结构,如果其中元素(p1, p2, p3...)不是 Promise,就会先调用下面讲到的 Promise.resolve
方法,将参数转为 Promise 实例关于 Promise 的状态与数据:
fulfilled
,新 Promise 对象的状态才会变成 fulfilled,此时 p1、p2、p3 的返回值(有次序地)组成一个数组,传递给p的回调函数。与 Promise.all()
类似,但是新 Promise 的状态与回调函数数据来源于 p1, p2, p3 中最先状态发生变化的那个。
(1)参数是一个 Promise 实例
如果参数是 Promise 实例,那么 Promise.resolve
将不做任何修改、原封不动地返回这个实例。
(2)参数是一个 thenable
对象
thenable
对象指的是具有 then
方法的对象(在 Java 里通常形象地说是一个类实现了 thenable
接口),比如下面这个对象。
// 便于理解,将其视为一个伪 Promise
let thenable = {
then: function(resolve, reject) {
// 在这里可以 resolve 与 reject
}
};
Promise.resolve
方法会将这个对象转为 Promise 对象,然后就立即执行 thenable
对象的 then
方法。then
方法可以接收 resolve
和 reject
做为参数,改变
let p1 = Promise.resolve(thenable);
p1;
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
(3)参数不是具有 then 方法的对象,或根本就不是对象
返回一个新的 Promise 对象
[[PromiseStatus]]
为 Resolved
[[PromiseValue]]
为传入的参数(4)不带任何参数
相当于 (3)中传入 undefined
// 用于回调链尾部的收尾处理
Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected)
.catch(function (reason) {
// 抛出一个全局错误
setTimeout(() => { throw reason }, 0);
});
};
// 用于在回调链尾部接一个普通的回调函数
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};