我现在正在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/