一尘不染

正确编写承诺循环的方式。

javascript

如何正确构造一个循环以确保以下的 promise调用 和链接的 logger.log(res) 通过迭代同步运行?

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





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); 的顺序

有什么建议?


阅读 282

收藏
2020-04-25

共1个答案

一尘不染

我不认为这可以保证调用logger.log(res)的顺序;

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

有什么建议?

很多。最重要的是您使用手动创建承诺反模式 仅做

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

第二,该while功能可以简化很多:

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

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

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'));
2020-04-25