具有超时的Node.js异步迭代

时间:2017-05-16 23:00:14

标签: javascript node.js asynchronous

对node.js和javascript有点新意。尝试让我的foreach调用一个函数,然后进行远程调用。我希望每个人之间有延迟,但似乎无法确定设置超时的位置。

我知道我的setTimeout位于下面的错误位置,但是将其作为示例放在那里。

var likeRecommendation = function (recommendation, callback) {
    context.Client.like(recommendation._id, function (error, data) {
        recommendation['drupal_user_uid'] = context.message.uid;
        recommendation['drupal_user_uuid'] = context.message.uuid;
        if (error) return callback(new Error('Could not like recommendations'));
        context.broker.publish('saves_swipes_publication', recommendation, function (err, publication) {
            if (err) return callback(new Error('Could queue swipes to save'));
                publication.on('error', console.error);
            });
            console.log('Liked!');
            return callback()
        });
    }

    async.forEach(context.recommendations, likeRecommendation, function (error) {
        if (!error) return done(null);
        done(new Error('Could not like recommendations'));
    });
}

3 个答案:

答案 0 :(得分:0)

setTimeout必须放在回调代码的末尾。

这是一个可能的解决方案(注意使用async.forEach

var likeRecommendation = function (recommendation, callback) {
    context.Client.like(recommendation._id, function (error, data) {
      recommendation['drupal_user_uid'] = context.message.uid;
      recommendation['drupal_user_uuid'] = context.message.uuid;
      console.log(recommendation);
      if (error) return done(new Error('Could not like recommendations'));
      context.broker.publish('saves_swipes_publication', recommendation, function (err, publication) {
        if (err) throw err
        publication.on('error', console.error);
      });
      console.log('Liked!');
      return callback()
    });
}

function iterateWithTimeout(list, ctx, timeoutDuration) {
  var currentIndex = 0;
  (function invoke() {
    list[currentIndex](ctx, function(error) {
      if (!error) return done(null);
      done(new Error('Could not like recommendations'));
      setTimeout(function() {
        if (++currentIndex < list.length) {
          invoke();
        }
      }, timeoutDuration);
    });
  })();
}

// Interval is 1 second for now
iterateWithTimeout(context.recommendations, likeRecommendation, 1000);

答案 1 :(得分:0)

所以使用“async.eachSeries”而不是“async.forEach”就是解决方案!

一如既往地感谢您的帮助!

答案 2 :(得分:0)

请参阅超时,警告您的一个回调丢失,另一个回放不正确。

 var likeRecommendation = function (recommendation, callback) {
    context.Client.like(recommendation._id, function (error, data) {
        recommendation['drupal_user_uid'] = context.message.uid;
        recommendation['drupal_user_uuid'] = context.message.uuid;
        if (error)
            setTimeout(function(){return callback(new Error('Could not like recommendations'))}, 100);
        else {
            context.broker.publish('saves_swipes_publication', recommendation, function (err, publication) {
                if (err)
                    setTimeout(function(){return callback(new Error('Could queue swipes to save'))}, 100);
                else
                {
                    publication.on('error', console.error);
                    setTimeout(function(){ return callback();}, 100);
                }

            });
       }
    });
}

async.forEach(context.recommendations, likeRecommendation, function (error) {
    if (!error) return done(null);
    done(new Error('Could not like recommendations'));
});
}