Promise 基本API 与 调度器
文档
前提:如果异步之间存在依赖关系就需要层层嵌套回调 因此形成回调地狱
-
Promise在新建时 内部操作(resolve reject前的代码 这好比是同步代码)就立即执行
-
缺点:
- 当处在未完成状态时,不能确定是出来什么阶段
- promise的内部错误不会反馈到外部 得用catch捕获 内部消化
- 不能暂停取消promise 一旦启动 无法中途取消
-
优点
- 避免回调地狱
- 链式调用:在上一个操作执行成功后再开始下一个操作 通过return返回结果下一层的
.then()
-
Promise.all()和Promise.race()是并行运行异步操作的两个组合式工具。 -
三种状态pending (fulfilled)resolved rejeted 状态修改后就不能变化!
-
then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。返回新的promise对象 因此能采用链式调用 -
catch()正常执行返回的是resolved状态 -
Promise.all()需要所有的promise参数都要执行完才能执行.then()- 当有一个Promise参数失败后 不需要管另外的请求是否的结束
- 如果作为参数的 Promise 实例,自己定义了
catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。自己执行完catch()后变成resolved就不会执行Promise的catch()只会相应一个catch()
/* 设置的简单Promise */
const PromiseA = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('PromiseA')
resolve() // rejected()
}, 200)
})
.then(() => {
console.log('PromiseA then')
})
.catch(err => {
console.log('PromiseA catch')
})
const PromiseB = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('PromiseB')
resolve() // rejected()
}, 500)
})
.then(() => {
console.log('PromiseB then')
})
.catch(err => {
console.log('PromiseB catch')
})
/* Promise.All([ ]) */
Promise.all([PromiseA, PromiseB])
.then(() => {
console.log('PromiseAll then')
})
.catch(() => {
console.log('PromiseAll catch')
})
/* 当PromiseA/B 都是resolve() */
输出:PromiseA => PromiseA then => PromiseB => PromiseB then => PromiseAll then
/* 当PromiseA/B 有一个rejected() */
输出:PromiseA => PromiseA then => PromiseB => PromiseB then => PromiseAll then
/* 原因:PromiseA/B 自己catch捕获错误后 返回是Promise实例状态是resolved*/
-
Promise.allSettled()- 目的为了解决all()方法中有的 Promise出错 被catch捕获
- 无论是否有失败 都会执行到 then 并用对象 将结果包起来 能直接看到各自的 Promise 的执行情况
/* PromiseA/B如上 删除cach的捕获错误 A设置成resolve B设置成reject*/
Promise.allSettled([PromiseA, PromiseB])
.then(res => {
console.log(res)
console.log('PromiseAll then')
})
.catch(() => {
console.log('PromiseAll catch')
})
/*
输出:
PromiseA
PromiseA then
PromiseB
[
{ status: 'fulfilled', value: undefined },
{ status: 'rejected', reason: undefined }
]
PromiseAll then
*/
-
- 第一个运行快的结果
- 某个 Promise 变成
rejected状态而结束
-
Promise.any()一组Promise作为参数- 只要有一个参数是
fulfilled状态 包装实例就会变成fulfilled状态 - 所有参数实例都变成
rejected状态,包装实例就会变成rejected状态。
- 只要有一个参数是
-
Promise.finally一组Promise作为参数- 无论返回的Promise是什么状态 最终都会执行
-
Promise.try()同步操作 -
调度器 并行执行promise
class Scheduler {
constructor() {
this.arr = [] //保存Promise等待队列
this.maxnum = 2 //并发执行个数
this.runnum = 0 //正在执行的个数
}
add(promise) {
this.arr.push(promise)
}
start() {
for (let i = 0; i < this.maxnum; i++) {
this.request()
}
}
request() {
if (!this.arr || !this.arr.length || this.runnum >= this.maxnum) return
this.runnum++
/* 抽取出一个新的 Promise 执行 */
this.arr.shift().then(() => {
this.runnum--
/* 接着请求执行后面的promise */
this.request()
})
}
}
const scheduler = new Scheduler()
const addTask = (time, num) => {
scheduler.add(
() =>
new Promise(resolve => {
setTimeout(() => {
console.log(num)
resolve()
}, time)
})
)
}
addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')
scheduler.start()
/*
2 => 3 => 1 => 4
1 和 2 Promise先进入执行 2执行完再执行3(此时时间500ms) 3执行后(此时时间800ms)再执行 4
*/