【问题标题】:How do I process an element before moving on to the next one in a for each loop?在 for each 循环中移动到下一个元素之前,如何处理一个元素?
【发布时间】:2015-05-10 13:58:12
【问题描述】:
var prompt = ...
var connection = ...

prompt.start();

var property = {
  name: 'yesno',
  message: 'approve this screencast?',
  validator: /y[es]*|n[o]?/,
  warning: 'Must respond yes or no',
  default: 'no'
};

connection.queryAsync('SELECT * FROM screencasts WHERE approved = 0')
  .spread(function(screencasts) {
    screencasts.forEach(function(screencast) {
      console.log('Title: "' + screencast.title + '".');
      prompt.get(property, function(err, res) {
        console.log('Command-line input received:');
        console.log('  result: ' + res.yesno);
      });
    });
  });

目标:枚举screencasts 并以交互方式提示用户批准或拒绝它们。

问题:我认为问题在于,循环根本没有阻塞,导致下一个元素被处理得太快:

如何在“处理”序列中的下一个元素之前等待用户输入值?

【问题讨论】:

标签: javascript prompt bluebird


【解决方案1】:

有人提到了mapSeries,这让我想到了example,它展示了如何避免 mapSeries,而是使用bluebird的map

我的结果是这样的:

var promise = ...   
var prompt = ...
var connection = ...

promise.promisifyAll(prompt);
...

connection.queryAsync('SELECT * FROM screencasts WHERE approved = 0')
  .spread(function(screencasts) {
    var current = promise.resolve();
    promise.map(screencasts, function(screencast) {
      current = current.then(function() {
        console.log('Title: "' + screencast.title + '".');
        return prompt.getAsync(property);
      }).then(function(res) {
        console.log(res);
      });
      return current;
    });
  });

它似乎运作良好。不过,我很好奇。 map 是不是最适合这个功能?

【讨论】:

  • 不,在这里使用Promise.map 是不合适的。您也可以通过这种方法使用原始的screencasts.forEach。相反,你应该使用Promise.reduce,这样你就可以避免写出这个current = current.then(…)的东西。
  • 你能告诉我怎么做吗,Bergi?谢谢你的评论,伙计。
猜你喜欢
  • 2019-11-29
  • 1970-01-01
  • 2019-10-01
  • 2014-12-16
  • 2020-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多