正确的写入循环的方法。 [英] Correct way to write loops for promise.

查看:204
本文介绍了正确的写入循环的方法。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何正确构建循环以确保以下承诺调用并且链式 logger.log(res)通过迭代同步运行? (bluebird)

How to correctly construct a loop to make sure the following promise call and the chained logger.log(res) runs synchronously through iteration? (bluebird)

db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise

我尝试了以下方法(方法来自http://blog.victorquinn.com/javascript-promise-while-loop

var Promise = require('bluebird');

var promiseWhile = function(condition, action) {
    var resolver = Promise.defer();

    var loop = function() {
        if (!condition()) return resolver.resolve();
        return Promise.cast(action())
            .then(loop)
            .catch(resolver.reject);
    };

    process.nextTick(loop);

    return resolver.promise;
});

var count = 0;
promiseWhile(function() {
    return count < 10;
}, function() {
    return new Promise(function(resolve, reject) {
        db.getUser(email)
          .then(function(res) { 
              logger.log(res); 
              count++;
              resolve();
          });
    }); 
}).then(function() {
    console.log('all done');
}); 

虽然它似乎有用,但我不认为它保证了呼叫的顺序 logger.log(res);


有什么建议吗?

Any suggestions?

推荐答案


我认为它不能保证调用logger.log(res)的顺序;

I don't think it guarantees the order of calling logger.log(res);

实际上,确实如此。该语句在 resolve 调用之前执行。

Actually, it does. That statement is executed before the resolve call.


有任何建议吗?

Any suggestions?

很多。最重要的是您使用创建-promise-manual antipattern - 只做

Lots. The most important is your use of the create-promise-manually antipattern - just do only

promiseWhile(…, function() {
    return db.getUser(email)
             .then(function(res) { 
                 logger.log(res); 
                 count++;
             });
})…

其次,功能可以简化为很多:

Second, that while function could be simplified a lot:

var promiseWhile = Promise.method(function(condition, action) {
    if (!condition()) return;
    return action().then(promiseWhile.bind(null, condition, action));
});

第三,我不会使用循环(带有闭包变量)但是用于循环:

Third, I would not use a while loop (with a closure variable) but a for loop:

var promiseFor = Promise.method(function(condition, action, value) {
    if (!condition(value)) return value;
    return action(value).then(promiseFor.bind(null, condition, action));
});

promiseFor(function(count) {
    return count < 10;
}, function(count) {
    return db.getUser(email)
             .then(function(res) { 
                 logger.log(res); 
                 return ++count;
             });
}, 0).then(console.log.bind(console, 'all done'));

这篇关于正确的写入循环的方法。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆