如何将闭包转换为承诺

时间:2018-05-18 22:17:06

标签: javascript node.js

我在for categories保存后,在for循环中使用闭包将类别保存到article表。

article.save(function (err, newArticle) {
    if (err) throw err;
    console.log('article created ', newArticle._id);

    for (var i = 0; i < categories.length; i++) {

        (function (index) {
            var category_article = new category_article_model({
                "category": categories[index],
                "article_id": newArticle._id
            });

            category_article.save(function (err, new_category_article) {
                if (err) throw err;
            })
        }(i));
    }

    return res.status(res.statusCode).send(newArticle);
})

如何将上述内容转换为使用承诺?

1 个答案:

答案 0 :(得分:2)

您似乎正在使用支持promises的MongoDB。然后,我们可以使用async/await(node&gt; = 7.6)来使代码更清晰,并使用Promise.all等待所有类别都保存。

app.post('/some/article', async(req, res) => {
                        // ^^^ notice async keyword
    const newArticle = await article.save();
    console.log('article created ', newArticle._id);

    // This will return an array of promises
    const categoryPromises = categories.map(category => {
        return new category_article_model({
            "category": category,
            "article_id": newArticle._id
        }).save(); // return a promise
    })

    // Promise.all takes an array of promises and waits
    // Until all promises are fulfilled
    await Promise.all(categoryPromises);

    // All categories are saved

    res.status(res.statusCode).send(newArticle);
});

作为旁注,您应该停止使用var并开始使用let/const,这样做,您可以删除代码的封闭,无论如何都不需要。

&#13;
&#13;
const categories = [1,2,3,4];
for (let i = 0; i < categories.length; i++) {
   // No need for closures
   setTimeout(() => console.log(`Using let: ${categories[i]}`))
}


for (var j = 0; j < categories.length; j++) {
   // without closure it doesn't work
   setTimeout(() => console.log(`Using var: ${categories[j]}`))
}
&#13;
&#13;
&#13;

检查以下问题:What's the difference between using "let" and "var" to declare a variable in JavaScript?