Promises(nodejs,bluebird)的问题:进程退出而不等待孩子完成

problems with Promises (nodejs, bluebird): process exits wihtout waiting for childs to be finished

我是 Promises 的新手,我肯定在编写错误的代码(我还不明白 Promises 是如何工作的)。

根据下面的代码,我预计 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
        })
}

这只是一个小错误,几乎是错字:您在 map 回调中遗漏了 return

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;
        })
);

(事实上,如果您开始 使用简洁的箭头,然后返回并添加日志记录行并将其转换为冗长的箭头,我不会感到惊讶,但是忘记添加 return。这是一个常见错误。)