如何从forEach循环实现平坦的承诺数组?

时间:2015-09-25 14:46:31

标签: javascript promise q

我正在尝试利用一系列承诺(通过Q&节点子进程 - 承诺库)来利用Windows WMIC命令来提取驱动器号,可用空间和总大小,如下所示:

var stdout = '';
var exec = require('child-process-promise').exec;

exec('wmic logicaldisk where drivetype=3 get caption', { capture: ['stdout', 'stderr'] })
    .then(function(result) {
        var data = result.stdout.split('\r\n');
        data = data.splice(1, data.length - 3);
        data = data.map(Function.prototype.call, String.prototype.trim);
        data.forEach(function(drive) {
            // This is where I am getting hung up
        });
    })
    .then(function(result) {
        console.log(result);
    })
    .fail(function(err) {
        console.error(err);
    });

正如您在上面的代码中所做的那样,我从WMIC的初始执行中返回一个驱动器号的数组,但在此之后,我将需要运行WMIC几次,具体取决于第一个查询返回的驱动器数。例如,如果我的数据数组如下:

['C:','D:']

我需要运行:

wmic logicaldisk where caption="C:" get freespace
wmic logicaldisk where caption="C:" get size
wmic logicaldisk where caption="D:" get freespace
wmic logicaldisk where caption="D:" get freespace

虽然我想从一个扁平的承诺链中做到这一点来汇总结果,但我似乎无法理解如何做到这一点。我已经看到了其他几个问题,其中建议使用“减少”,但似乎无法计算如何将其应用于我目前的情况。

1 个答案:

答案 0 :(得分:1)

通过迭代数据并将每个调用的结果存储到数组中的exec来创建Promise集合。然后通过将数组传递给Q#all来等待所有Promise的解析。

使用嵌套forEach

var promises = [];

data.forEach(function (drive) {
    var commands = [
        'wmic logicaldisk where caption="' + drive + '" get freespace',
        'wmic logicaldisk where caption="' + drive + '" get size'
    ];

    commands.forEach(function (cmd) {
        promises.push(exec(cmd, {capture: ['stdout', 'stderr']}));
    });
});

return Q.all(promises);

或使用reducemap

var promises = data.reduce(function (result, drive) {
    var commands = [
        'wmic logicaldisk where caption="' + drive + '" get freespace',
        'wmic logicaldisk where caption="' + drive + '" get size'
    ].forEach(function (cmd) {
        result.push(exec(cmd, {capture: ['stdout', 'stderr']}));
    });

    return result;
}, []);

return Q.all(promises);