javascript - Promise.all() 解析,但它不应该(node.js)

标签 javascript node.js asynchronous promise

我现在正在node.js中尝试类似的事情:

var exec = require('child_process').exec
var write = require('fs-writefile-promise')

function run() {
    var myArray = [];   
    var execs = [];

    for (var i = 1; i <= 7; i++) {
        (function(cntr) {
            write('file-' + i + '.txt', someString)
            .then(function (filename) {
                execs.push(new Promise(function(resolve, reject) {
                    exec('cat ' + 'file-' + cntr + '.cnf', function(error, stdout, stderr) {
                        console.log(cntr + ' ' + stdout);
                        if (stdout.search(/\bsomeString\b/) > -1) {
                            myArray.push(cntr);
                            resolve();
                        } 
                        else {
                            resolve();
                        }   
                    })
                }))
            })
            .catch(function (err) {
                console.error(err);
            });
        })(i);
    }
    return Promise.all(execs).then(function() {
        return new Promise(function(resolve) {
            resolve(myArray);
        }) 
    })
}

run().then(function(result) {
    console.log(result);
});

如您所见,我正在创建多个运行 exec() 的 Promise,并且每个 Promise 都会在 exec() 完成时解析。 然后,我等待在 Promise.all(execs) 中解析每个 Promise,以将 myArray 作为 Promise 返回。然而,当我最后执行 run() 函数时,它返回一个空数组。我想这与 Promise.all() 有关,因为即使 execs 中的某些 Promise 尚未解决,它也会解决,但我不确定,那就是为什么我真的需要一些帮助。有谁知道我在代码中哪里犯了错误?

提前非常感谢您!

#编辑1

var exec = require('child_process').exec
var write = require('fs-writefile-promise')

function run() {
    var myArray = [];   
    var execs = [];

    for (var i = 1; i <= 7; i++) {
        (function(cntr) {
            return new Promise(function(resolve, reject) {
                fs.writeFile('file-' + i + '.txt', someString, (err) => {
                    if (err) {
                        reject();
                    }
                    else {
                        resolve();
                    }
                });
            })
            .then(function (filename) {
                execs.push(new Promise(function(resolve, reject) {
                    exec('cat ' + 'file-' + cntr + '.cnf', function(error, stdout, stderr) {
                        console.log(cntr + ' ' + stdout);
                        if (stdout.search(/\bsomeString\b/) > -1) {
                            myArray.push(cntr);
                            resolve();
                        } 
                        else {
                            resolve();
                        }   
                    })
                }))
            })
            .catch(function (err) {
                console.error(err);
            });
        })(i);
    }
    return Promise.all(execs).then(function() {
        return new Promise(function(resolve) {
            resolve(myArray);
        }) 
    })
}

run().then(function(result) {
    console.log(result);
});

最佳答案

您的两次尝试都存在许多问题。第一次尝试的问题是,您在异步操作后填充了 execs 数组,因此当您实际将数组传递给 Promise.all() 时,其中没有任何内容,因此 Promise .all() 没有什么可等待的。

此外,您不只是使用已经创建的 Promise,因此您最终会做出比需要的更多的 Promise。

一般来说,最好在主逻辑之外“ promise ”异步操作,然后让所有逻辑都由 promise 驱动,而不是将 promise 与普通回调混合和匹配。这是尝试解决这些问题的版本:

var exec = require('child_process').exec
var write = require('fs-writefile-promise')

// make promisified version of exec
function execP(file, options) {
    return new Promise(function(resolve, reject) {
        exec(file, options, function(err, stdout, stderr) {
            if (err) return resolve(err);
            resolve({stdout: stdout, stderr: stderr});
        });
    });
}

function run() {
    var promises = [];
    for (var i = 1; i <= 7; i++) {
        promises.push(write('file-' + i + '.txt', someString).then(function(filename) {
            return execP(filename);
        }));
    }
    return Promise.all(promises).then(function(results) {
        // results is an array of {stdout: xxx, stderr: yyy} objects
        // process those results into a new array of just indexes
        var final = [];
        results.forEach(function(data, index) {
            if (data.stdout.search(/\bsomeString\b/) > -1) {
                final.push(index);
            }
        });
        return final;
    });
}

run().then(function(results) {
    // array of indexes that contained the desired search string
}, function(err) {
    // process error here
});

注意:这会并行运行所有 exec 操作,这就是您的原始代码所做的。如果您想按顺序运行它们,也可以这样做,但需要一些调整。

关于javascript - Promise.all() 解析,但它不应该(node.js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34841946/

相关文章:

javascript - JSPlumb 在悬停时显示连接标签

javascript - 使用 jQuery 在特定位置查找元素?

node.js - 使用 nodejs 从 Twilio 发送多个媒体文件

javascript - 通过将数组值转换为表来创建 .txt 文件

mysql - 使用 mysql 和 node.js 更新 foreach 外部的变量值

时间:2019-03-17 标签:c#asyncawait

javascript - getjson 出现意外 token 错误

javascript - 检查数组包含另一个数组的每个元素

node.js - Mongoose 中的 "__v"字段是什么

c# - 如何通过C# async/await为同步程序添加并发