承诺的顺序和并行处理

时间:2018-04-09 06:37:30

标签: javascript promise

这个想法是按顺序迭代数组,但并行处理子数组中的每个项目。

  1. 一旦记录#1被并行处理,它就会移动到记录#2并且并行处理它的项目,依此类推。所以基本上它是顺序性和并行性的组合。

  2. Concat all导致单维数组和显示。 (待定)

  3. 如果输入包含数组数组。

    var items = [
        ["item1", "item2"],
        ["item3", "item4"],
        ["item5", "item6"],
        ["item7", "item8"],
        ["item9", "item10"]
    ]
    

    处理这些项目的行动。

    function action(item) {
        return new Promise(function(resolve, reject){
            setTimeout(function(){
                resolve(item + ":processed");
            }, 100)
        });
    }
    

    尝试

    describe("", function(){
        this.timeout(0);
    
        it("should", function(done){
            items.reduce(function(accumulator, currentValue, currentIndex, array){
                return accumulator.then(function(result){
                    return new Promise(function(resolve, reject){
                        Promise.all(currentValue.map(action))
                            .then(resolve, reject);
                    });
                });
            }, Promise.resolve())
    
        });
    
    });
    

    期望

    理想情况下,干净的简约和功能方法无状态)将结果返回给调用者。

    尝试2

    var chain = items.reduce(function(accumulator, currentValue, currentIndex, array){
        return accumulator.then(function(result){
            return new Promise(function(resolve, reject){
                Promise.all(currentValue.map(action))
                    .then(resolve, reject);
            });
        });
    }, Promise.resolve());
    
    chain.then(console.log, console.error); // I need all results here
    
      
        

    仅显示最后结果。 ['item9:processed','item10:processed']

      

    根据答案编辑最终解决方案。

    var chain = items.reduce(function(accumulator, currentValue, currentIndex, array){
        return accumulator.then(function(result){
            return new Promise(function(resolve, reject){
    
                Promise.all(currentValue.map(action))
                    .then(function(data){
                        resolve(result.concat(data)) // new array
                    }, reject);
            });
    
        });
    }, Promise.resolve([]));
    
    chain.then(console.log, console.error);
    

2 个答案:

答案 0 :(得分:2)

一种方法:

var items = [
    ["item1", "item2"],
    ["item3", "item4"],
    ["item5", "item6"],
    ["item7", "item8"],
    ["item9", "item10"]
]

function action(item) {
    return new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve(item + ":processed");
        }, 100)
    });
}

function process(items) {
  return items.reduce((m, d) => {
    const promises = d.map(i => action(i));
    let oldData;
    return m.then((data) => {
        oldData = data;
        return Promise.all(promises);
      })
      .then(values => {
        //oldData.push(...values);
        oldData.push.apply(oldData, values);
        return Promise.resolve(oldData);
      })
  }, Promise.resolve([]))
}

process(items).then(d => console.log(d))

//Prints:

// ["item1:processed","item2:processed","item3:processed","item4:processed","item5:processed","item6:processed","item7:processed","item8:processed","item9:processed","item10:processed"]

答案 1 :(得分:0)

这样做的简单功能方法就像

  • 通过承诺返回异步函数来映射具有并行数据的子数组
  • Promise.all()生成的promises数组
  • .then()
  • Promise.all() in a recursive fashion阶段对子数组进行排序

ES6;像spread syntax / rest parametersarray destructuring这样的工具对于这项工作非常方便。



var items = [["item1", "item2"],
             ["item3", "item4"],
             ["item5", "item6"],
             ["item7", "item8"],
             ["item9", "item10"]],
    act   = i => new Promise(v => setTimeout(v, 1000, `${i}: processed`)),
    seqps = ([is,...iss]) => is && Promise.all(is.map(i => act(i)))
                                          .then(([p,q]) => (console.log(`${p} and ${q}`),
                                                            seqps(iss)));
seqps(items);