Promise是什么?
Promise是ES6新增的语法,是一种异步编程的一种解决方案,Promise本质上是一个绑定了回调的对象。 Promise在一定程度上解决了回调函数的书写结构问题,解决了回调地狱的问题。Promise可以看作是一个状态机,它有三种状态:pending,fulfilled,rejected,其中初始状态是pending,可以通过函数resolve(表示成功)把状态变为fulfilled,或者通过函数reject(表示失败)把状态变为rejected。状态一经改变就不能再次变化,及状态发生凝固Promise 的状态变化只能发生一次。
Promise的状态可变吗?
不可变
Promise.resolve()
将现有对象转为Promise对象,状态为fullfilled
Promise.reject()
将现有对象转为Promise对象,状态为rejected
prmoise.all()
核心:等待所有结果完成,都成功走then方法,有一个失败就走catch方法
该方法接收一个可迭代对象(如Array,Map,Set),返回一个Promise(新期约),只有当该数组中所有的Promise完成后才会有pending转变为resolved执行then里面的回调函数;若数组中有任意一个promise被拒绝则会执行失败回调,即catch方法会捕获到首个被执行的reject函数。通过该方法获得的成功结果的数组里面的数据顺序和接收到的promise数组顺序是一致的。
Promise.allSelected()
核心:发起多个请求(不管成功失败),等到所有请求后再做下一步处理,都走then方法拿到成功或者失败的结果
返回一个在所有给定的promise都已经fulfilled或rejected后的promise,都走then方法拿到成功或者失败的结果,并带有一个对象数组,每个对象表示对应的promise结果
Promise.race()
核心: 同时发起几个异步请求,谁先有结果就拿谁的
应用:检测请求超时
Promise.race()和Promise.all()一样都是将多个Promise实例组合成一个Promise的静态方法 不同的是:Promise.race()当传入的数组中有任意一个promise被拒绝或者成功,不管成功或者失败,都会采用第一个promise作为返回值,若成功则执行then,失败执行catch。
Promise.any()
核心:同时发起多个请求,有一个成功就走then拿到成功结果,全部失败就走catch 类似筛选成功结果
区别于Promise.all()
, Promise.any()
只要有一个成功,就执行then方法拿到成功的结果,如果没有一个成功,就走catch方法返回一个所有子项组成的失败的promise的组合
Promise.any() 和 Promise.race() 的区别
Promise.race()的 promise 在你给它的第一个 promise 被拒绝时被拒绝; any
的 promise 不是,因为可能会实现另一个 promise 。
Promise.any()的 promise 的拒绝原因是 AggregateError
(多个promise共同错误的集合) , 但是 race
的拒绝原因将是第一个被拒绝的 promise 的拒绝原因。
Prmoise.all()和Promise.allSelected()区别
Prmoise.all()在接受失败状态时会走.catch方法, Promise.allSelected()则走.then方法
手撕Promise的then和catch
function PromiseZ(executor) {
this.status = 'pending'
this.result = undefined
this.cb = []
const resolve = (res) => {
if (this.status !== 'pending') return
this.result = res
this.status = 'fulfilled'
this.cb.forEach((item) => {
item.success && item.success(res)
})
}
const reject = (res) => {
if (this.status !== 'pending') return
this.result = res
this.status = 'rejected'
this.cb.forEach((item) => {
item.fail && item.fail(res)
})
}
executor(resolve, reject)
}
PromiseZ.prototype.then = function (successCB, failCB) {
if(!successCB) successCB = res => res
// 错误参数转接头
if(!failCB) failCB = res => res
return new PromiseZ((resolve, reject) => {
//同步处理
if (this.status === 'fulfilled') {
const result = successCB && successCB(this.result)
if (result instanceof PromiseZ) {
result.then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
} else {
resolve(result)
}
}
if (this.status === 'rejected') {
const result = failCB && failCB(this.result)
if (result instanceof PromiseZ) {
result.then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
} else {
reject(result)
}
}
if (this.status === 'pending') {
// 异步处理
this.cb.push({
success: () => {
const result = successCB(this.result)
if (result instanceof PromiseZ) {
result.then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
} else {
resolve(result)
}
},
fail: () => {
const result = failCB(this.result)
if (result instanceof PromiseZ) {
result.then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
} else {
reject(result)
}
},
})
}
})
}
PromiseZ.prototype.catch = function(failCB){
this.then(undefined, failCB)
}
自己根据网上教程总结的,比较粗糙,大佬们有错误可以指出