【问题标题】:Implement Promise.chain([...]) in Javascript?在 Javascript 中实现 Promise.chain([...])?
【发布时间】:2018-01-18 11:10:57
【问题描述】:

小问题:为什么 Javascript 中没有 Promise.chain(类似于 Promise.all)?我的实现还好吗?

我的“编解码器”行为错误:

  1. 从 XML 文件中读取图形
  2. 创建所有节点(创建方法返回一个promise)
  3. 等待所有节点创建完成
  4. 在节点之间创建所有边

问题:创建节点(第 2 步)的数据库调用顺序在执行时混淆了。

解决方案:在执行方法之前,我必须以正确的顺序链接数据库调用。

/**
 * chains a list of functions (that return promises) and executes them in the right order
 * [function() {return Promise.resolve();}, function() {return Promise.resolve();}]
 *
 * @param funcs is an array of functions returning promises
 * @returns {Promise}
 */
function chain_promises(funcs) {
    if (funcs.length < 1) {
        return Promise.resolve();
    }
    var i = 0;
    return chain_executor(funcs, i);
}

/**
 * Recursive help method for chain_promises
 * 1) executes a function that returns a promise (no params allowed)
 * 2) chains itself to the success resolve of the promise
 *
 * @param funcs is an array of functions returning promises
 * @param i is the current working index
 */
function chain_executor(funcs, i) {
    var promise = funcs[i]();
    return promise.then(function(){
        console.log(i);
        if (funcs.length > i+1) {
            return chain_executor(funcs, i+1);
        } else {
            return Promise.resolve();
        }
    })
}

【问题讨论】:

标签: javascript es6-promise


【解决方案1】:

使用 Array#reduce 可以创建这个函数

const chain_promises = arrayOfFn => arrayOfFn.reduce((promise, fn) => 
    promise.then(results => 
        fn().then(result => 
            results.concat(result)
        )
    ), Promise.resolve([])
);

或者如果你喜欢单线

const chain_promises = arrayOfFn => arrayOfFn.reduce((promise, fn) => promise.then(results => fn().then(result => results.concat(result))), Promise.resolve([]));

这些还有一个额外的好处是解析的值都在.then中可用

例如

const chain_promises = arrayOfFn => arrayOfFn.reduce((promise, fn) => 
    promise.then(results => 
        fn().then(result => 
            results.concat(result)
        )
    ), Promise.resolve([])
);

const wait_promise = (time, result) => new Promise(resolve => setTimeout(resolve, time, result));
var funcs = [ 
    () => wait_promise(300, 'p1').then(value => ({value, date: new Date()})),
    () => wait_promise(400, 'p2').then(value => ({value, date: new Date()})),
    () => wait_promise(100, 'p3').then(value => ({value, date: new Date()}))
];
const start = new Date();
chain_promises(funcs)
.then(results => 
    results.reduce((a, b) => {
        console.log(b.value, b.date - a);
        return b.date;
    }, start)
);

此外,将空数组传递给此函数不会中断 - 您最终会得到一个空数组作为解析值

【讨论】:

    猜你喜欢
    • 2014-01-10
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多