节点返回BluebirdJS Promise

时间:2016-04-05 20:02:17

标签: javascript node.js bluebird

我有一个小问题,这个脚本运行正常,有一个问题,“runTenant”方法没有返回一个promise(需要从“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)”的承诺没有得到解决。

好像不明显,我对承诺很恐怖。仍然努力让我的头围绕着他们。

非常感谢任何帮助/指导!

3 个答案:

答案 0 :(得分:1)

你不应该在这里使用Promise构造函数(基本上,也不应该使用其他任何地方),即使你使它工作也是antipattern。您从未解决过这个承诺 - 请注意Promise构造函数回调的resolve argumentPromise.resolve的功能完全不同。

如果你手头有像Bluebird这样强大的诺言库,你就不应该使用async库。

  

好像不明显,我对承诺很恐怖。

也许你会想看看我的rules of thumb写承诺函数。

这是你的功能应该是什么样的:

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
        }
      });
    });
  });
}

答案 1 :(得分:0)

您需要返回所有嵌套的承诺。我无法运行此代码,因此不会修复它。但希望它可以帮助你理解缺少的东西。

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
            }
        });
}

答案 2 :(得分:0)

您在runTenant函数中的承诺永远不会得到解决。您必须调用resolvereject函数来解决承诺:

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

你不应该在cb函数中传递runTenant,使用promises chain:

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