Promise 对象用于表示一个异步操作最终的完成或失败,以及结果值。
在创建Promise时,创建者也不知道它的结果。
一个Promise有三种状态:pending、fufilled、rejected
Promise的创建
创建Promise时传入一个函数,函数的参数为resolve和reject两个处理函数。通常,在执行一些异步操作后,根据异步操作的结果,调用resolve或reject,改变promise的状态。
let promise1 = new Promise((resolve, reject) => {
console.log("before setTimeout", timer)
setTimeout(() => {
console.log("before resolve", timer)
let random = Math.random()
if(random < 0.5){
resolve(random)
}
else{
reject(random)
}
}, 800)
})
Promise的链式调用
因为 Promise.prototype.then 和 Promise.prototype.catch 会返回一个Promise对象,所以Promise可以被链式调用。
Promise.prototype.then(onFulfilled, onRejected)
在then中的返回值,如果不是一个Promise类型的值,会被包装成一个立刻resolve的Promise,这个值就会是resolve传给下一个then的onFulfilled处理函数的参数。如果返回值是一个Promise,那么就执行这个Promise,等待其执行结果。
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("resolve value ", 1)
resolve(1)
}, 100)
})
promise1.then(res =>{
console.log("get value", res, "time: ", timer)
console.log("return value ", res + 1, "time: ", timer)
return res + 1
})
.then(res => {
console.log("get value", res, "time: ", timer)
console.log("return Promise", "time: ", timer)
return new Promise((resolve, reject) => {
console.log("new promise created", "time: ", timer)
setTimeout(() => {
console.log("new promise resolved value ", res + 1, " time: ", timer)
resolve(res + 1)
}, 500);
})
})
.then(res => {
console.log("get value", res, "time: ", timer)
console.log("return value ", res + 1, "time: ", timer)
return res + 1
})
Promise.prototype.catch(onRejected)
对应了Promise.prototype.then(..., onRejected)
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("reject value ", 1)
reject(1)
}, 100)
})
promise1.then(res => {
console.log("get value", res, "time: ", timer)
})
.catch(res => {
console.log("catch value in catch", res, "time: ", timer)
})
如果then中已经添加了onReject处理,那么不会触发catch;
如果then中在执行fulfilled是时候产生异常,那么会触发catch;
promise1.then(res => {
console.log("get value", res, "time: ", timer)
return notExist // 触发异常
})
.catch(res => {
console.log("in catch", res, "time: ", timer)
})
Promise.race()
race会创建一个新的promise,以第一个结束的promise为准,第一个结束的成功就是成功,失败就是失败。
Promise.race([promise1, promise2, promise3]).then(res => {
console.log("race end", res)
})
.catch(res => {
console.log("race end in catch", res)
})
Promise.all()
all会创建一个新的promise,若有一个promise失败,那么就是失败,都成功,那么返回的是按顺序的结果数组。
Promise.all([promise1, promise2, promise3]).then(res => {
console.log("all end", res)
})
.catch(res => {
console.log("all end in catch", res)
})
Promise.resolve()
若参数为一个值,那么创建一个promise,并立刻resolve这个值
Promise.resolve(1).then(res => {
console.log("resolved ", res)
})
若参数为一个promise,那么就返回这个promise
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2)
}, 200);
})
Promise.resolve(promise1).then(res => {
console.log("resolved ", res)
})
.catch(res => {
console.log("rejected ", res)
})
Promise.reject()
Promise.reject(reason)
Promise 与 Async/Await
有 async 关键字的 function 会返回一个 promise 对象,以函数的返回值调用 resolve,若函数发生异常,则调用reject;
await expression,如果expression是一个promise,就返回promise的处理结果,否则就返回值本身;
await 会暂停当前函数的执行,等待promise的结果,若promise正常执行,则resolve的值会作为await的结果;若promise失败,那么await会抛出异常;
有 async 关键字的 function 内可以使用 await 关键字;await 只在 async 方法里有效,在其他地方使用 await 会抛出异常;
线性调用:按顺序执行,按顺序结束
async function sequentialStart(){
const slow = await resolveAfter2Seconds();
console.log(slow); // 2. this runs 2 seconds after 1.
const fast = await resolveAfter1Second();
console.log(fast); // 3. this runs 3 seconds after 1.
}
并发调用:一起执行,按顺序结束
async function concurrentStart() {
const slow = resolveAfter2Seconds(); // starts timer immediately
const fast = resolveAfter1Second(); // starts timer immediately
// 1. Execution gets here almost instantly
console.log(await slow); // 2. this runs 2 seconds after 1.
console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
}
// 等价
async function concurrentPromise() {
return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => {
console.log(messages[0]); // slow
console.log(messages[1]); // fast
});
}
并行执行:一起执行,谁快谁先结束
async function parallelPromise() {
resolveAfter2Seconds().then((message)=>console.log(message));
resolveAfter1Second().then((message)=>console.log(message));
}
// 等效
async function parallel() {
await Promise.all([
(async()=>console.log(await resolveAfter2Seconds()))(),
(async()=>console.log(await resolveAfter1Second()))()
]);
}