Promise
Promise是异步编程的一种解决方案,
Promise 状态
pending
:进行中fulfilled
:已成功rejected
:已失败
Promise 实例化对象的状态只能从pending
->
fulfilled,pending->
rejected,不能
从fulfilled到reject或者反之也不行
基本用法
console.log("①");
new Promise((resolve, reject) => {
console.log("②");
if(true){
resolve();
}else{
reject()
}
console.log("③");
})
console.log("④");
Promise 构造函数接受一个函数
作为参数,该函数有两个参数resolve
和reject
;
resolve
:将Promise对象的状态从未完成
变成成功
;reject
:将Promise对象的状态从未完成
变成失败
;
const promise = new Promise((resolve,reject) => {
if(true){
resolve('success');
}else{
reject('fail')
}
})
promise.then((res) =>{},(err)=>{})
resolve
后的Promise
reject
后的Promise
- Promise新建后就会立即执行
new Promise((resolve,reject) => {
console.log("①")
resolve();
console.log("②")
})
执行结果是① 和 ② 顺序打印
then
- then 中返回
非Promise
- then 中返回
Promise实例
抛出异常
没有
return 内容,默认是fulfilled
const p = new Promise((resolve, reject) => {
resolve("success")
})
const p1 = p.then(res => {
return res;
})
console.log(p1, "p1");
const p2 = p.then(res => {
return new Promise(() => { });
})
console.log(p2, "p2");
const p3 = p.then(res => {
throw new Error("error")
})
console.log(p3, "p3");
const p4 = p.then(() => {
})
console.log(p4, "p4");
链式调用
new Promise((resolve, reject) => {
console.log("1");
resolve("2")
console.log("3");
reject("4")
}).then(res => {
console.log("5>>>", res);
return res
}).then(res => {
console.log("6", ">>>", res);
}).then((res => {
console.log("7", ">>>", res);
return new Promise((resolve, reject) => {
console.log("8");
reject("9")
})
})).then((res) => {
console.log("10", ">>>", res);
}).catch(err => {
console.log("11", "error>>>", err);
})
console.log("执行完了");
cath
用于指定发生错误时的回调函数
new Promise((resolve, reject) => {
console.log(1);
reject("error>>>>>>>>")
}).catch(err => {
console.log(2);
return new Promise((resolve, reject) => {
console.log("err", err);
resolve(3)
})
}).then(res => {
console.log("res", res);
})
const p = new Promise((resolve, reject) => {
resolve(n + 1) // n is not defined
})
p.then(res => {
console.log(res);
})
setTimeout(() => {
console.log(1);
}, 2000)
上述代码中,存在语法错误,浏览器运行到这一行,会打印错误提示,但是不会退出进程、终止脚本执行
const p = new Promise((resolve, reject) => {
reject("error")
}).catch(err => {
console.log(err);
console.log(x);
}).catch(err => {
console.log("catch =>>> error");
})
第二个catch
方法用来捕获前一个catch
方法抛出的错误
finally
finally()
方法用于指定不管Promise对象状态如何,都会执行的操作
const p = new Promise((resolve, reject) => {
resolve(1);
reject(2);
}).then(res => {
console.log("success");
}).catch(err => {
console.log("error");
}).finally(() => {
console.log("finally");
}).finally(() => {
console.log("finally2");
}).then((res) => {
console.log(res, "res1");
}).then((res) => {
console.log(res, "res2");
}).catch((err) => {
console.log(err, "err");
})
Promise.all()
Promise.all()
方法用于将多个Promise实例,包装成一个新的Promise实例
const p1 = new Promise((resolve, reject) => {
resolve("p1")
})
const p2 = new Promise((resolve, reject) => {
resolve("p2")
})
const p3 = new Promise((resolve, reject) => {
resolve("p3")
})
Promise.all([p1, p2, p3]).then(res => {
console.log(res);
})
const p1 = new Promise((resolve, reject) => {
resolve("p1")
})
const p2 = new Promise((resolve, reject) => {
resolve("p2")
})
const p3 = new Promise((resolve, reject) => {
resolve("p3")
})
const p4 = new Promise((resolve, reject) => {
reject("p4")
})
Promise.all([p1, p2, p3, p4]).then(res => {
console.log(res);
}).catch(err => {
console.log("err>>", err);
})
Promise.race()
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p1")
}, 5000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2")
}, 3000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p3")
}, 3000)
})
const p4 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p4")
}, 2000);
})
const p = Promise.race([p1, p2, p3, p4]).then(res => {
console.log("res>>>", res);
return res;
}).catch(err => {
console.log("err>>", err);
})
console.log(p, "p");
以上代码中,只要p1、p2、p3、p4 之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数
Promise.allSettled()
用来确定一组异步操作是否都结束了(无论成功或者失败)
只有等到参数数组中所有的Promise对象都发生变更(不管是fulfilled还是rejected),返回的Promise对象才会发生状态变更
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p1")
}, 5000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p2")
}, 3000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p3")
}, 3000)
})
console.time("p")
await Promise.allSettled([p1, p2, p3]).then(res => {
console.log("res>>>", res);
return res;
}).catch(err => {
console.log("err>>", err);
})
console.timeEnd("p")
console.log("执行完了");
上面代码中,只有等Promise.allSettled()
都执行完成后,才会执行打印,该方法返回新的Promise实例,一定状态变更,状态总是fulfilled
,不会变成rejected
,状态变成fulfilled
后,它的回调函数会接收到一个数组作为参数,该数组的每个成员对应前面数组的每个Promise对象
Promise.any()
const p1 = Promise.any([Promise.resolve(1), Promise.resolve(-1), Promise.reject(Infinity)]).then(res => {
console.log(res, "res");//1
})
const p2 = Promise.any([Promise.reject(2), Promise.resolve(100), Promise.reject(Infinity)]).then(res => {
console.log(res, "res"); //100
})
const p3 = Promise.any([Promise.reject(Infinity), Promise.reject(-1), Promise.reject(1000)]).then(res => {
console.log(res, "res");
}).catch(err => {
console.log(err, "err"); // AggregateError: All promises were rejected 'err'
console.log(err instanceof AggregateError, "err"); //true 'err'
})
Promise.any()
方法的参数数组包含Promise操作,其中只要有一个变成fulfilled
,Promise.any()
返回的对象就变成了fulfilled
,如果都变成rejected
那么就会变成rejected
。
Promise.resolve()
有时候需要将对象转为Promise对象,Promise.resolve()
方法就起到了作用。
- 参数是Promise实例
如果参数是Promise实例,那么将不做任何修改,返回这个实例; - 如果参数是一个
thenable
对象
const thenAble = {
then(resolve, reject) {
resolve("thenAble>> thenFuction")
}
}
Promise.resolve(thenAble).then(res => {
console.log(res, "res"); // thenAble>> thenFuction
})
Promise.resolve()
方法会将这个对象转为Promise 对象,然后立即执行其中的then方法
- 参数不是具有
then()
方法的对象,或者是不是对象
如果参数是一个原始值,或者不具有then()
方法的对象,这Promise.resolve()
方法返回一个新的Promise对象,状态为resolved
。
const p = Promise.resolve("none")
console.log(p);
- 不带任何参数
setTimeout(() => {
console.log(1);
}, 2000)
Promise.resolve().then((res) => {
console.log(res);
console.log(2);
})
console.log(3);
// 3
// undefined
// 1
Promise.reject()
Promise.reject("1").then(res => {
console.log(res, "res");
}).catch(err => {
console.log(err, "err");
})
// 1 err
Promise.try()
有一个函数,不知道它是同步执行还是异步执行,想用一种方法如果它是同步的代码就让他同步执行,异步就异步执行;
- 方法一
function f1() {
setTimeout(() => {
console.log("异步代码");
}, 2000)
}
function f2() {
console.log("同步代码");
}
Promise.try(() => {
f1()
f2()
}).then(res => {
console.log(res, "res");
}).catch(err => {
console.log(err, "err");
})
console.log("执行完了");