ES6 中的 Promise(三)
2021-02-12 本文已影响0人
F_wind
《深入理解ES6》阅读随笔
响应多个 Promise
在 Promise 中还有两个静态方法,可以用来控制响应多个 Promise 对象。
Promise.all()
Promise.all() 方法接收一个可迭代 Promise 数组作为参数,然后按照数组顺序依次执行各个 Promise,在所有 Promise 均完成的情况下,最终会在 then 中获取到一个数组输出结果:
const p1 = new Promise((resolve, reject) => {
resolve(10)
})
const p2 = Promise.resolve(20)
const p3 = Promise.resolve(30)
const p4 = Promise.all([p1, p2, p3])
p4.then((value) => {
console.log(Array.isArray(value))
console.log(value)
}).catch((err) => {
console.log('catch', err)
})
// 输出
// true
// [ 10, 20, 30 ]
如果其中有一个 Promise 被拒绝,那么会终止流程:
const p1 = new Promise((resolve, reject) => {
resolve(10)
})
const p2 = Promise.reject(20)
const p3 = Promise.resolve(30)
const p4 = Promise.all([p1, p2, p3])
p4.then((value) => {
console.log(Array.isArray(value))
console.log(value)
}).catch((err) => {
console.log('catch', err)
})
// 输出
// catch 20
Promise.race()
Promise.race() 方法同样会接收一个可迭代 Promise 数组对象作为参数,只不过,它会按抢占方式在 then 中优先输出完成或者拒绝最快的 Promise,在解决函数中获取到的参数是一个 Promise 返回值:
const p1 = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(10)
},10)
})
const p2 = Promise.resolve(20)
const p3 = Promise.resolve(30)
const p4 = Promise.race([p1, p2, p3])
p4.then((value) => {
console.log(Array.isArray(value))
console.log(value)
}).catch((err) => {
console.log('catch', err)
})
// 输出
// false
// 20
即时后面再出现异常,也不影响前面的正常输出:
const p1 = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(10)
},10)
})
const p2 = Promise.resolve(20)
const p3 = Promise.reject(30)
const p4 = Promise.race([p1, p2, p3])
p4.then((value) => {
console.log(Array.isArray(value))
console.log(value)
}).catch((err) => {
console.log('catch', err)
})
// 输出
// false
// 20
Promise 继承
Promise 作为内建对象,也同样支持继承:
class newPromise extends Promise {
success(resolve, reject) {
return this.then(resolve, reject)
}
failed(reject) {
return this.catch(reject)
}
}
const p1 = new newPromise((resolve, reject) => {
resolve(100)
})
p1.success((data) => {
console.log('success', data)
}).failed((err) => {
console.log('err', err)
})
// 输出
// success 100
派生的新类同样继承了 Promise 的静态方法 resolve、reject、all、race 等。
异步执行多个 Promise 任务
function run(task) {
let taskIterator = task();
let result = taskIterator.next();
(function step() {
if (!result.done) {
const promise = Promise.resolve(result.value)
promise.then(function (data) {
result = taskIterator.next(data)
step()
}).catch((err) => {
result = taskIterator.throw(err)
step()
});
};
}());
}
const fs = require('fs')
function readfile(name) {
return new Promise((resolve, reject) => {
fs.readFile(name, { encoding: 'utf8' }, function (err, data) {
if (err) {
reject(err)
}
resolve(data)
})
})
}
run(function* () {
const content = yield readfile('test.txt')
console.log('content:', content)
console.log('done')
})
// 输出
// content: Hi,man!
// done
未来将会实现的新方式(当前时间已实现)
使用新的 async + await 方式,用同步的写法来调用异步的 Promise 对象。该方式笔者已经在频繁的使用了,其跟 yield 比起来,使用更加简洁易懂:
const fs = require('fs')
function readfile(name) {
return new Promise((resolve, reject) => {
fs.readFile(name, { encoding: 'utf8' }, function (err, data) {
if (err) {
reject(err)
}
resolve(data)
})
})
}
(async function () {
const content = await readfile('test.txt')
console.log('content:', content)
console.log('done')
}())
// 输出
// content: Hi,man!
// done