Promise 对象用于表示一个异步操作最终的完成或失败,以及结果值。
在创建Promise时,创建者也不知道它的结果。
一个Promise有三种状态:pending、fufilled、rejected
创建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.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) })race会创建一个新的promise,以第一个结束的promise为准,第一个结束的成功就是成功,失败就是失败。
Promise.race([promise1, promise2, promise3]).then(res => { console.log("race end", res) }) .catch(res => { console.log("race end in catch", res) })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(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(reason)
有 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()))() ]); }