节点 return BluebirdJS Promise

Node return BluebirdJS Promise

我有一个小问题,这个脚本运行良好,有一个问题,"runTenant" 方法没有返回承诺(需要从 "all()".

解决

此代码:

Promise.resolve(runTenant(latest)).then(function() {
  end();
});

调用此代码:

function runTenant(cb) {
  return new Promise(function() {
    //global var
    if (!Tenant) {
      loadCoreModels();
      Tenant = bookshelf.core.bs.model('Tenant');
    }

    new Tenant().fetchAll()
      .then(function(tenants) {

        if (tenants.models.length == 0) {
          return;
        } else {
          async.eachSeries(tenants.models, function(tenant, next) {

            var account = tenant.attributes;
            Promise.resolve(db_tenant.config(account)).then(function(knex_tenant_config) {
              if (knex_tenant_config) {
                db_tenant.invalidateRequireCacheForFile('knex');
                var knex_tenant = require('knex')(knex_tenant_config);
                var knex_pending = cb(knex_tenant);
                Promise.resolve(knex_pending).then(function() {
                  next(null, null);
                });
              } else {
                next(null, null);
              }
            });

          });
        };
      });
  });
}

来自 runTenant 的代码工作正常,但它停止了并且没有继续到 "end()",因为来自 "runTenant(latest)" 的承诺没有得到解决。

好像不明显,我不善于承诺。仍在努力了解它们。

非常感谢任何 help/direction!

您需要 return 所有嵌套的承诺。我不能 运行 此代码,所以这不是放弃修复。但希望它能帮助您了解缺少的内容。

function runTenant(cb) {
    //global var
    if (!Tenant) {
        loadCoreModels();
        Tenant = bookshelf.core.bs.model('Tenant');
    }

    return new Tenant().fetchAll() //added return
        .then(function (tenants) {

            if (tenants.models.length == 0) {
                return;
            } else {
                var promises = []; //got to collect the promises
                tenants.models.each(function (tenant, next) {

                    var account = tenant.attributes;
                    var promise = Promise.resolve(db_tenant.config(account)).then(function (knex_tenant_config) {
                        if (knex_tenant_config) {
                            db_tenant.invalidateRequireCacheForFile('knex');
                            var knex_tenant = require('knex')(knex_tenant_config);
                            var knex_pending = cb(knex_tenant);
                            return knex_pending; //return value that you want the whole chain to resolve to
                        }
                    });
                    promises.push(promise); //add promise to collection
                });
                return Promise.all(promises); //make promise from all promises
            }
        });
}

您在 runTenant 函数中的承诺从未得到解决。您必须调用 resolvereject 函数来解析 promise:

function runTenant() {
  return new Promise(function(resolve, reject) {
    // somewhere in your code
    if (err) {
      reject(err);
    } else {
      resolve();
    }
  });
});

而且你不应该在 runTenant 函数中传递 cb,使用承诺链:

runTenant()
 .then(latest)
 .then(end)
 .catch(function(err) {
   console.log(err);
 });

你根本不应该在这里使用 Promise 构造函数(基本上,也不应该在其他任何地方使用),即使你让它工作它也会是一个 antipattern. You've never resolved that promise - notice that the resolve argument to the Promise constructor callback is a very different function than Promise.resolve.

如果手边有像 Bluebird 这样强大的 promise 库,则不应使用 async 库。

As if it weren't apparent, I am horrible at promises.

也许你会想看看我的 rules of thumb 编写 promise 函数。

您的函数应如下所示:

function runTenant(cb) {
  //global var
  if (!Tenant) {
    loadCoreModels();
    Tenant = bookshelf.core.bs.model('Tenant');
  }
  return new Tenant().fetchAll().then(function(tenants) {
    // if (tenants.models.length == 0) {
    //  return;
    // } else
    // In case there are no models, the loop iterates zero times, which makes no difference
    return Promise.each(tenants.models, function(tenant) {
      var account = tenant.attributes;
      return db_tenant.config(account).then(function(knex_tenant_config) {
        if (knex_tenant_config) {
          db_tenant.invalidateRequireCacheForFile('knex');
          var knex_tenant = require('knex')(knex_tenant_config);
          return cb(knex_tenant); // can return a promise
        }
      });
    });
  });
}