【问题标题】:Using Async and Promises that are all rejected leads to async never completing使用全部被拒绝的 Async 和 Promises 会导致异步永远不会完成
【发布时间】:2014-07-11 23:11:24
【问题描述】:

我正在使用asyncpromise 运行种子脚本,但在所有promses 都是rejected 的情况下,脚本永远不会完成。

因为它是一个播种脚本,它被设置为不播种已经有数据的模型。

这是(删节的)我的代码

知道我错过了什么吗?

seed = function(collectionName, data) {
  return new Promise(function(fulfill, reject) {
    var collection = collections[collectionName];
    collection.find().exec(function(err, found) {
      if (found.length > 0) {
        console.log("There are", found.length, collectionName, "records in the database already.");
        reject();
      } else {
        collection.createEach(data, function(err, models) {
          if (err || _.isUndefined(models)) {
            console.log("Could not create", collectionName, "collection!");
            reject();
          } else {
            collection.find().exec(function(err, found) {
              fulfill(found);
            });
          }
        });
      }
    });
  });
};

run = function(models, done) {
  async.each(models, function(modelName, next) {
    seed(modelName, modelData[modelName]).then(function(codes) {
      console.log("Seeded", codes.length, modelName, "records.");
      next();
    }, function(err){
      console.log("Seeding of", modelName, "failed", err.stack);
      done(err);
    });
  }, done);
};

run(["widget", "thingo", "dooverlackey"], function(err){
  if (err) console.error("Completed with errors", err);
  else console.log("Completed without errors");
  process.exit();
});

【问题讨论】:

  • 此外,如果我将错误消息传递给reject("my error"),那么整个过程都会在第一个错误处停止,这也不是我想要的。我只是希望它跳过任何已经有数据的模型。
  • Promises 已经提供了异步聚合和结构化。真的没有理由在这里使用异步模块。您可以简单地 .then 在 for 循环中链接它们而无需异步。
  • 谢谢 Benjamin - 这是一个很好的观点,但是使用 async 我可以将另一个模型添加到我的数组中,瞧。也许摆脱 Promise 结构反而会简化事情。
  • 你可以 .then 用 promises 得到同样的中提琴

标签: javascript node.js asynchronous promise


【解决方案1】:

在您的代码中,如果您拒绝调用seed(),那么您的代码将转到您调用done().then() 中的拒绝处理程序。因此,您自己的结构已告诉它如果在此代码中被拒绝,则停止处理:

seed(modelName, modelData[modelName]).then(function(codes) {
  console.log("Seeded", codes.length, modelName, "records.");
  next();
}, function(err){
  console.log("Seeding of", modelName, "failed", err.stack);
  // upon fail from seed, stop processing
  done(err);
});

您可以更改拒绝处理程序(传递给.then() 的第二个回调),以便它继续处理,或者您可以将seed() 更改为仅在出现无法继续的严重错误时拒绝。

虽然有许多不同的方式可以使用 Promise,但对于无法继续的严重失败保留拒绝可能更传统,这意味着如果出现严重错误,则将 seed() 函数更改为仅 reject()。当它只是因为工作已经完成而发现它无事可做时,它只会resolve()并让整个过程继续下去。

【讨论】:

    猜你喜欢
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 2013-11-23
    相关资源
    最近更新 更多