节点 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
函数中的承诺从未得到解决。您必须调用 resolve
或 reject
函数来解析 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
}
});
});
});
}
我有一个小问题,这个脚本运行良好,有一个问题,"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
函数中的承诺从未得到解决。您必须调用 resolve
或 reject
函数来解析 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
}
});
});
});
}