🗺️ [ECMAScript6] 17. Promise对象
Promise含义
基本用法
Promise.prototype.then
会返回新的Promise对象(返回的不是原来Promise实例,因此可以链式调用)
Promise.prototype.catch
Promise.prototype.finally
等同于
javascriptCopy
promise
.finally(() => {
// 语句
});
// 等同于
promise
.then(
result => {
// 语句
return result;
},
error => {
// 语句
throw error;
}
);Promise.all
Promise.race
有一个Promise率先完成,包装实例的状态也会跟着改变。
应用:请求响应超时
javascriptCopy
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。
Promise.any
只要有一个Promise变成fulfilled 包装实例会变成fulfilled状态。所有Promise状态变成rejected包装实例状态会变成 rejected。
Promise.allSettled
用于确定所有异步操作都结束了,不管里面的Promise状态是fulfilled 还是rejected,都会出发回掉
Promise.resolve
需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。
等价于
javascriptCopy
new Promise(resolve => resolve())resolve参数
javascriptCopy
Promise.resolve(new String('1')).then(a => console.log(a))
// String {'1'}javascriptCopy
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function (value) {
console.log(value); // 42
});javascriptCopy
Promise.resolve(1).then(a => console.log(a))
// 1Promise.reject
生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行(本轮“事件循环”(event loop)的结束时执行)。
javascriptCopy
Promise.reject('').catch(() => console.log('456'));
console.log('123');
// 123
// 456等价于
javascriptCopy
new Promise((_resolve, reject) => reject())应用
Promise.try[提案]
实战中有种情况:是不想去分函数F 是同步还是异步函数,但都想用Promise去处理数据用 catch。来捕获异常。一般会采用下面的做法。
javascriptCopy
const f = () => console.log('now');
Promise.resolve().then(f);
console.log('next');
// next
// now但这有个问题。如果函数F 是同步函数,但这样处理之后却变成异步执行了(在本轮事件循环末尾执行)。
有没有一种方法,让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API 呢?回答是可以的,并且还有两种写法。
javascriptCopy
const f = () => console.log('now');
(async () => f())();
console.log('next');
// now
// nextjavascriptCopy
const f = () => console.log('now');
(() => new Promise(resolve=> resolve(f)))
.then(...)
.catch(...)使用Promise.try统一捕捉同步和异步错误 。比如,连接数据库函数可能会抛出同步错误(比如连接数据库异常等)或者异步返回数据。
javascriptCopy
Promise.try(()=>database.usrs.get({id: userId}))
.then(...)
.catch(...)