Promises(nodejs,bluebird)的问题:进程退出而没有等待子节点完成

时间:2018-01-19 13:08:57

标签: javascript node.js knex.js

我是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
        })
}

1 个答案:

答案 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}}。这是一个常见的错误。)