Nodejs Bluebird Promises - 如何知道是否所有的promises都被执行了

时间:2014-11-08 06:58:09

标签: javascript node.js

根据this回答,已经创建了承诺,但是在不等待子进程输出的情况下执行方法'(以及#39; done') ,我需要有一个方法,在完全执行所有子进程后调用,如何使用bluebird api完成?

示例代码



 var Promise = require('bluebird')
    var exec   = require('child_process').exec

    // Array with input/output pairs
    var data = [
        ['input1', 'output1'],
        ['input2', 'output2'],
        .....
    ]

    var PROGRAM = 'cat'
    Promise.some(data.map(function(v) {
    var input = v[0]
    var output = v[1]

    new Promise(function(yell, cry) {
        exec('echo "' + input + '" | ' + PROGRAM, function(err, stdout) {
            if(err) return cry(err)
                yell(stdout)
            })
        }).then(function(out) {
            if(out !== output) throw new Error('Output did not match!')
        })
    }),data.length)

    .then(function() {
        // Send succes to user if all input-output pair matched
    }).catch(function() {
        // Send failure to the user if any one pair failed to match
    })




这里'然后'即使在子进程完成之前,函数也会立即执行。

1 个答案:

答案 0 :(得分:3)

Promise.some()期望一组promises作为其第一个参数。您正在将data.map()的结果传递给它,但是您对data.map()的回调永远不会返回任何内容,因此.map()不会构造一个承诺数组,因此Promise.some()没有任何内容等待,所以它立即调用它是.then()处理程序。

此外,如果您要等待所有承诺,那么您也可以使用Promise.all()代替。

这就是我想你想要的。

的变化:

  1. 切换到Promise.all(),因为您要等待所有承诺。
  2. 返回新的Promise,以便.map()创建承诺数组。
  3. 将输出检查移动到原始承诺中,因此它可以拒绝而不是抛出,它似乎将所有结果检查移动到一个位置。
  4. 添加了所有缺失的分号。
  5. cryyell更改为resolvereject,以便外部人员更加熟悉正常的承诺名称。
  6. 以下是代码:

    var Promise = require('bluebird');
    var exec   = require('child_process').exec;
    
    // Array with input/output pairs
    var data = [
        ['input1', 'output1'],
        ['input2', 'output2']       
    ];
    
    var PROGRAM = 'cat';
    Promise.all(data.map(function(v) {
        var input = v[0];
        var output = v[1];
    
        return new Promise(function(resolve, reject) {
            exec('echo "' + input + '" | ' + PROGRAM, function(err, stdout) {
                if(err) {
                    reject(err);
                } else if (stdout !== output) {
                    reject(new Error('Output did not match!'));
                } else {
                    resolve(stdout);
                }
            });
        });
    })).then(function() {
        // Send succes to user if all input-output pair matched
    }).catch(function() {
        // Send failure to the user if any one pair failed to match
    });