关于学习Promise的前置知识
event loop的执行顺序
一开始整个脚本作为要给宏任务执行
执行过程中同步代码直接执行,宏任务进入到宏任务队列,微任务进入到微任务队列。
当前宏任务执行完出队,检查微任务列表,有则一次执行,直到全部执行完
执行浏览器UI线程的渲染工作
检查是否有Web Worker任务,有则执行
执行完本轮的宏任务,回到2,依次循环,直到宏任务和微任务都为空
宏任务及微任务
常见的宏任务:
setTimeout
setInterval
MessageChannel
I/O,时间队列,script(整体代码块)
微任务
MutationObserver(浏览器环境)
Promise.then/catch/finally
process.nextTick(Node环境)
什么是Promise
Promise,给予调用者一个承诺,过一会儿返回数据给你,就可以创建一个promise对象,用于解决回调地狱这种情况而诞生
当我们new一个promise,此时我们需要传递一个回调函数,这个函数为立即主席那个的,称之为(executor)
这个回调函数,我们需要传入两个参数回调函数,reslove,reject(函数可以进行传参)
当执行了reslove函数,会回调promise的,then函数。
当执行了reject函数,会回调promise的,catch函数。
Promise共有三种状态,pending(待定),fulfilled(已兑现,执行了resolve函数),rejected(已拒绝,执行了reject函数)
resolve不同值的区别
如果resolve传入一个普通的值或者对象,之恶能传递接收一个参数,那么这个值会作为then回调的参数
如果resolve传入的是另外一个Promise,那么这个新的Promise会决定原Promise的状态。
如果resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,then方法会传入resolve,reject函数。此时的promise状态取决于你调用了resolve,还是reject函数。这种模式也被称为thenable。
一些Promise的常用API
Promise.all()
接收一个Promise数组,数组中如有非Promise项,则此项当做成功
如果所有Promise都成功,则返回成功结果数组
如果有一个Promise失败,则返回这个失败结果
// 手写Promise.all()
Promise.MyAll = function (promises) {
let arr = [],
count = 0
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
Promise.resolve(item).then(res => {
arr[i] = res
count += 1
if (count === promises.length) resolve(arr)
}, reject)
})
})
}
Promise.any()
接收一个Promise数组,数组中如有非Promise项,则此项当做成功。与Promise.all()相反
如果有一个Promise成功,则返回这个成功结果
如果所有Promise都失败,则报错
//手写Promise.any()
Promise.MyAny = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach((item, i) => {
})
})
}
Promise.race()
接收一个Promise数组,数组中如有非Promise项,则此项当做成功
哪个Promise最快得到结果,就返回那个结果,无论成功失败
手写Promise.race()
Promise.MyRace = function (promises) {
return new Promise((resolve, reject) => {
// 这里不需要使用索引,只要能循环出每一项就行
for (const item of promises) {
Promise.resolve(item).then(resolve, reject)
}
})
}
Promise.allSettled
接收一个Promise数组,数组中如有非Promise项,则此项当做成功
把每一个Promise的结果,集合成数组,返回
static allSettled(promises) {
return new Promise((resolve, reject) => {
const res = []
let count = 0
const addData = (status, value, i) => {
res[i] = {
status,
value
}
count++
if (count === promises.length) {
resolve(res)
}
}
promises.forEach((promise, i) => {
if (promise instanceof MyPromise) {
promise.then(res => {
addData('fulfilled', res, i)
}, err => {
addData('rejected', err, i)
})
} else {
addData('fulfilled', promise, i)
}
})
})
}