Javascript&许诺承诺Q - 关闭问题

时间:2013-11-29 23:41:45

标签: javascript node.js coffeescript promise q

我正在使用Node.js和Q来编写服务器端异步代码。我是承诺的新手(我一般都是异步编程的新手),而且我遇到了一些麻烦,我无法通过盯着Q文档来解决。这是我的代码(它是coffeescript - 让我知道你是否想要看到javascript):

templates = {}
promises = []
for type in ['html', 'text']
    promises.push Q.nfcall(fs.readFile
        , "./email_templates/#{type}.ejs"
        , 'utf8'
        ).then (data)->
            # the problem is right here - by the time
            # this function is called, we are done
            # iterating through the loop, and the value 
            # of type is incorrect
            templates[type] = data
Q.all(promises).then(()->
    console.log 'sending email...'
    # send an e-mail here...
).done ()->
    # etc

希望我的评论解释了这个问题。我想迭代一个类型列表,然后为每种类型运行一系列promise,但问题是type的值在promise的范围之外被更改。我意识到,对于这么短的清单,我可以展开循环,但这不是一个可持续的解决方案。如何确保每个承诺都能看到type的本地正确值?

2 个答案:

答案 0 :(得分:3)

您必须将数据赋值闭包封装在另一个闭包中,以便在执行内部闭包之前保留type的值。

有关详细信息:http://www.mennovanslooten.nl/blog/post/62

答案 1 :(得分:1)

我不了解CoffeeScript,但这应该适用于JS:

var promises = [];
var templates = {};
var ref = ['html', 'text'];

for (var i = 0, len = ref.length; i < len; i++) {
    var type = ref[i];

    promises.push(Q.nfcall(fs.readFile, "./email_templates/" + type + ".ejs", 'utf8').then((function (type) {
        return function (data) {
            return templates[type] = data;
        };
    }(type))));
}

Q.all(promises).then(function() {
    return console.log('sending email...');
    // ...
}).done(function() {
    // ...
});

编辑:CoffeeScript翻译:

templates = {}
promises = []
for type in ['html', 'text']
    promises.push Q.nfcall(fs.readFile
        , "./email_templates/#{type}.ejs"
        , 'utf8'
        ).then do (type)->
            (data)->
                 templates[type] = data
Q.all(promises).then(()->
    console.log 'sending email...'
).done ()->
    console.log '...'

重要的部分是:

).then do (type)->
    (data)->
        templates[type] = data