Promise 对象
p1 的状态会传递给 p2 (p2 状态无效)
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error("fail")), 3000);
});
const p2 = new Promise(function (resolve, reject) {
setTimeout(() => resolve(p1), 1000);
});
p2.then((result) => console.log("【res】", result))
.catch((error) => console.log("【err】", error));
// 【err】Error: fail
调用resolve
或reject
并不会终结 Promise 的参数函数的执行
new Promise((resolve, reject) => {
console.log(0);
resolve(1);
console.log(2); // 依旧执行
}).then((r) => {
console.log(r);
});
console.log(3);
// 0
// 2
// 3
// 1
Promise 状态已经变成 resolved,再抛出错误是无效的
const promise = new Promise(function (resolve, reject) {
resolve("ok");
throw new Error("test");
});
promise
.then(function (value) {
console.log(value);
})
.catch(function (error) {
console.log(error);
});
// ok
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。(中间的 then 代码不会执行)
new Promise((resolve, reject) => {
console.log(1);
reject("Error1");
})
.then((res) => {
conso.log(2);
conso.log(res);
})
.catch((err) => {
console.log(3);
console.log(err);
});
// 1
// 3
// Error1
Promise 对象抛出的错误不会传递到外层代码,“Promise 会吃掉错误”
new Promise((resolve, reject) => {
console.log(1);
// 下面一行会报错,因为x没有声明
resolve(x + "test");
console.log(2);
})
.then(() => {
console.log(3);
})
.catch((err) => {
console.log(err);
});
console.log('main')
// 1
// main
// ReferenceError: x is not defined
Promise.all 和 Promise.allSettled
Promise.all
Promise.all()方法接受一个数组作为参数,如果数组某一项不是 Promise 实例,会使用 Promise.resolve()将其转为 Promise 实例。
当数组每一项的状态都变成 fulfilled,p 状态才会 fulfilled。只要有一项状态变成 rejected,p 就变成 rejected。
const p = Promise.all([p1, p2, p3]);
注意,数组项的 Promise 实例,自己定义了 catch 方法,那么它一旦被 rejected,并不会触发 Promise.all()的 catch 方法。
const p1 = new Promise((resolve, reject) => {
resolve("hello");
}).catch((e) => e);
const p2 = new Promise((resolve, reject) => {
throw new Error("报错了");
}).catch((e) => e);
Promise.all([p1, p2])
.then((result) => console.log("success", result))
.catch((e) => console.log("error", e));
// success (2) ['hello', Error: 报错了...]
// 可以看到走的是then,而不是catch
Promise.allSettled
只有等到参数数组的所有 Promise 对象都发生状态变更(不管是 fulfilled 还是 rejected),返回的 Promise 对象才会发生状态变更。
该方法返回的新的 Promise 实例,一旦发生状态变更,状态总是 fulfilled,不会变成 rejected。
Promise.any
接受数组作为参数。只要参数实例有一个变成 fulfilled 状态,包装实例就会变成 fulfilled 状态;如果所有参数实例都变成 rejected 状态,包装实例就会变成 rejected 状态。
Promise.any([
fetch("https://v8.dev/").then(() => "home"),
fetch("https://v8.dev/blog").then(() => "blog"),
fetch("https://v8.dev/docs").then(() => "docs"),
])
.then((first) => {
// 只要有一个 fetch() 请求成功
console.log(first);
})
.catch((error) => {
// 所有三个 fetch() 全部请求失败
console.log(error);
});
Promise.resolve
参数是一个 Promise 实例
如果参数是 Promise 实例,那么 Promise.resolve 将不做任何修改、原封不动地返回这个实例。(就是说如果传入的是 rejected 状态的实例,那么后续依旧是 rejected)
参数是一个 thenable 对象
Promise.resolve()方法会将这个对象转为 Promise 对象,然后就立即执行 thenable 对象的 then()方法。
let thenable = {
then: function (resolve, reject) {
console.log(1)
resolve(42);
},
};
let p1 = Promise.resolve(thenable);
p1.then(function (value) {
console.log(value);
});
console.log(2)
// 2
// 1
// 42
参数不是具有 then()方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有 then()方法的对象,则 Promise.resolve()方法返回一个新的 Promise 对象,状态为 resolved。
不带有任何参数
直接返回一个 resolved 状态的 Promise 对象。
Promise.reject
Promise.reject()方法的参数,会原封不动地作为 reject 的理由,变成后续方法的参数。(就是它不会像 Promise.resolve 那样处理参数)