Promise
Promise为异步操作提供统一接口,使代码更加易读
// 传统写法
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// ...
});
});
});
});
// Promise 的写法
(new Promise(step1))
.then(step2)
.then(step3)
.then(step4);
Promise 三种状态
promise对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。
异步操作未完成(pending)
异步操作成功(fulfilled)
异步操作失败(rejected)
上面三种状态里面,fulfilled和rejected合在一起称为resolved(已定型)。 pending-> fulfilled(成功:传回值(value))/rejected(失败,抛出错误(error)) 一旦状态发生变化,就不会再有新的状态变化。 Promise 实例的状态变化只可能发生一次。
var promise = new Promise(function (resolve, reject) {
// ...
if (/* 异步操作成功 */){
resolve(value);
} else { /* 异步操作失败 */
reject(new Error());
}
});
then
then() 方法最多接受两个参数;第一个参数是 Promise 兑现时的回调函数,第二个参数是 Promise 拒绝时的回调函数。每个 .then()
返回一个新生成的 Promise 对象,这个对象可被用于链式调用。
var p1 = new Promise(function (resolve, reject) {
resolve('成功');
});
p1.then(console.log, console.error);
// "成功"
var p2 = new Promise(function (resolve, reject) {
reject(new Error('失败'));
});
p2.then(console.log, console.error);
// Error: 失败
链式调用
一个 Promise 的终止条件决定了链中下一个 Promise 的“已敲定”状态。链中每个已兑现的 Promise 的返回值会传递给下一个 .then()
,而已拒绝的 Promise 会把失败原因传递给链中下一个拒绝处理函数。
在每个 .then()
中处理被拒绝的 Promise 对于 Promise 链的下游有重要的影响。
错误必须立即被处理的情况下,必须抛出某种类型的错误以维护链中的错误状态。
在没有迫切需要的情况下,最好将错误处理留到最后一个
.catch()
语句。.catch()
其实就是一个没有为 Promise 兑现时的回调函数留出空位的.then()
。
myPromise
.then((value) => `${value} and bar`)
.then((value) => `${value} and bar again`)
.then((value) => `${value} and again`)
.then((value) => `${value} and again`)
.then((value) => {
console.log(value);
})
.catch((err) => {
console.error(err);
});
结果的值
返回一个新的 Promise
对象,该对象以给定的原因拒绝。
返回一个新的 Promise
对象,该对象以给定的值兑现。
如果值是一个 thenable 对象(即具有
then
方法),则返回的 Promise 对象会“跟随”该 thenable 对象,采用其最终的状态;否则,返回的 Promise 对象会以该值兑现。
通常,如果你不知道一个值是否是 Promise,那么最好使用
Promise.resolve(value)
将其转换成 Promise 对象,并将返回值作为 Promise 来处理。
const promiseA = new Promise((resolve, reject) => {
resolve(777);
});
// 此时,“promiseA”已经敲定了
promiseA.then((val) => console.log("异步日志记录有值:", val));
console.log("立即记录");
总结:.then会处理前一个 Promise的结果并且返回Promise,Promise 的结果会以 Promise 或者值的方式传给 .then。
async/await
async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。
// Some code
async function f() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // 等待,直到 promise resolve (*)
alert(result); // "done!"
}
f();
关键字 await
让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果,相比于 promise.then
,它只是获取 promise 的结果的一个更优雅的语法。并且也更易于读写。
这个函数在执行的时候,“暂停”在了 (*)
那一行,并在 promise settle 时,拿到 result
作为结果继续往下执行。所以上面这段代码在一秒后显示 “done!”。
Last updated