日常刻书

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 
上一篇下一篇

猜你喜欢

热点阅读