我是Promises的新手,我肯定在编写错误的代码(我还不了解Promise是如何工作的)。
从下面的代码中我预计只有在完成其他任何事情时才会执行process.exit(0);
。
但是在下面的代码中" console.log(step 2
)"永远不会执行(在控制台中看到),因为我认为process.exit(0)
在等待其他进程之前运行。有没有建议如何重组我的代码?
var wordsToProcess = ['e301', 'e260']; // array with many words (could be mora than 2)
var actions = wordsToProcess.map((str) => {
console.log('(1) step ');
ingredient_get(str)
.then((ingredient_id) => {
console.log('(2) step '); //!!!! never console.log
return ingredient_id; // never return ingredient_id
});
});
var results = Promise.all(actions);
results.then(ingredient_id => {
process.exit(0); // should somehow wait for all ingredient_ids to come
});
function ingredient_get(name) {
var q_ingredients = knex('ingredients')
.select('id').where('name', name)
.then(pick_id)
var q_synonyms = knex('synonyms')
.select('ingredient_id as id').where('name', name)
.then(pick_id)
return Promise.all([q_ingredients, q_synonyms])
.then(([id1, id2]) => {
return id1 || id2; // only one id would be true here
})
}
答案 0 :(得分:2)
这只是一个小小的错误,几乎是一个错字:你在return
回调中遗漏了map
:
var actions = wordsToProcess.map((str) => {
console.log('(1) step ');
return ingredient_get(str)
// ^^^^^^------------------------------------ add this
.then((ingredient_id) => {
console.log('(2) step ');
return ingredient_id;
});
});
因此,actions
只是填充了undefined
而不是对承诺的反应,所以Promise.all
没有任何承诺可以等待。
如果删除console.log
(或滥用逗号运算符,但是......不这样做),则可以使用简洁的箭头代替:
var actions = wordsToProcess.map((str) =>
ingredient_get(str)
.then((ingredient_id) => {
console.log('(2) step ');
return ingredient_id;
})
);
(事实上,如果您使用简明的箭头开始,我会不会感到惊讶,然后返回并添加了日志记录行并将其转换为详细箭头但忘记添加{ {1}}。这是一个常见的错误。)