我想将Promise与NodeJS一起使用,但似乎无法按预期工作。
我想按此顺序查看所有文件的LOG 1
,LOG 2
和LOG 3
。 LOG 4
被隐藏了...
但是我明白了:
LOG 1
LOG 3
LOG 1
LOG 3
LOG 1
LOG 3
SUCCESS LOG 2
SUCCESS LOG 2
SUCCESS LOG 2
SUCCESS LOG 2
我的代码:
var filePromise = _.map(files, function(file) {
var filePath = './sql/' + file;
fs.lstat(filePath, function(err, stats) {
if (stats.isFile() && file !== '.gitignore' && file !== 'index.js') {
fs.readFile(filePath, 'utf-8', function(err, data) {
console.log('LOG 1');
db.query(data).then(function() {
console.log(colors.green('SUCCESS LOG 2'));
}).catch(function() {
console.log(colors.red('ERROR LOG 2'));
});
console.log('LOG 3');
});
}
});
});
Promise.all(filePromise).then(function() {
console.log(colors.green('LOG 4'));
});
答案 0 :(得分:1)
为了使filePromise
包含一个Promise集合,您需要为map调用的每次迭代返回一个Promise。只有这样,才能正确评估对Promise.all
的呼叫。
var filePromise = _.map(files, function(file) {
return new Promise(function(resolve, reject) {
var filePath = './sql/' + file;
fs.lstat(filePath, function(err, stats) {
if (stats.isFile() && file !== '.gitignore' && file !== 'index.js') {
fs.readFile(filePath, 'utf-8', function(err, data) {
console.log('LOG 1');
db.query(data).then(function() {
console.log(colors.green('SUCCESS LOG 2'));
resolve();
}).catch(function() {
console.log(colors.red('ERROR LOG 2'));
reject();
});
console.log('LOG 3');
});
} else {
reject(new Error("failed condition"))
}
});
})
});
Promise.all(filePromise).then(function() {
console.log(colors.green('LOG 4'));
});
这不能解决控制台日志的顺序。那是一个单独的问题。您的控制台日志实际上并没有出现故障,它们正在按预期方式进行日志记录。但是,这是由于您正在对db.query
进行异步调用而引起的,该调用在被触发时不会阻止等待响应。而是在函数调用返回后立即执行下一行。
旁注::请确保处理传递给err
和fs.lstat
的内联回调函数的fs.readFile
参数。否则,将导致承诺在出现错误时永远无法完成。