如何在 promise.spread 内外使用 Q Promise 的结果
How to use results from Q Promise inside and outside of promise.spread
我最近开始为我的 Node.js 应用程序使用 q promise javascript 库。在我的代码中,我有一个条件来确定我是否应该执行 1 个或 3 个 promise 方法。然后我想执行返回承诺的方法数组并对结果执行额外的处理。
问题:如何使用内部和外部的结果.spread(...)
,以便将结果传递给其他方法?
一些背景:我正在构建一个 REST API,根据 POSTed JSON 正文的值,我必须首先使用 Sequelize 将记录插入数据库,得到响应(所以我知道自动生成的主键),然后使用该主键在其他 table 中插入记录。
var promiseMethods;
var someParam1, someParam2, someParam3 = 'Hello World';
if (someCondition == true) {
promiseMethods = [promiseMethod1(someParam1)];
} else {
promiseMethods = [
promiseMethod1(someParam1),
promiseMethod2(someParam2),
promiseMethod3(someParam3)];
}
Q.all(promiseMethods)
.spread(function(promseResult1,
promiseResult2,
promiseResult3) {
var model = {
result: promiseResult1
};
//Other code removed for brevity.
return DatabasePromise.save(model)
});
然后我希望能够执行类似以下假设代码的操作。
var result = add(promiseResult1)
var result2 = subtract(promiseResult2)
var result3 = multiply(promiseResult3)
基本上我想并行执行前 1 或 3 个返回承诺的方法,然后能够在之后多次使用承诺结果。
这里是我希望代码执行的更好的想法。这里的示例是我有一个产品 table,用户与该产品相关联。我想将数据插入这两个 table(以及第三个 table)。
var _ = require('lodash');
function insert(request, reply) {
var response;
var db = getDBConnection();
var step1Promises;
if (property == true) {
step1Promises = [
CommonModule.promiseMethodForProductUsers(db, userUUIDs)
];
} else {
step1Promises = [
CommonModule.promiseMethodForProductUsers(db, userUUIDs),
CommonModule.promiseMethod2(payload.data1, payload.data2),
CommonModule.promiseMethod3(db, payload.data3)
];
}
var step1 = Q.all(step1Promises);
var resolvedProductUsers;
var internalIDs;
var productPromise = step1.spread(function(productUsers, promiseMethod2, promiseMethod3) {
resolvedProductUsers = productUsers;
var currentUser = users[0].uid;
internalIDs = Q(_.pluck(resolvedProductUsers, 'uid'));
var product = db.Product.build({
product_name: productName,
last_edit_user_id: currentUser
});
return CommonModule.createProduct(db, product);
});
// When running, internalIDs is undefined.
var step2 = Q.all([
CommonModule.buildProductUsersModel(db, internalIDs, productPromise.tid),
CommonModule.buildOtherTableModel(db, productPromise.pid, currentUser.Id, otherData)
]);
step2.spread(function(usersToInsert, otherTableDataToInsert) {
CommonModule.saveProductUsers(db, usersToInsert);
CommonModule.saveOtherTableData(db, otherTableDataToInsert);
});
// The response must be a promise, otherwise this insert method will finish
// and return an empty result.
response = productPromise;
return reply(response);
}
您可以使用普通变量来缓存传播的结果以供进一步使用。
var result1, result2, result3;
Q.all([
method1,
method2,
method3
]).spread(function(
promiseResult1,
promiseResult2,
promiseResult3
){
result1 = promiseResult1;
result2 = promiseResult2;
result2 = promiseResult2;
...
<do something with result1>
}).then(function) {
// outside the spread
<do something with result2>
//
<do something with result3>
})
您还可以使用嵌套闭包来访问父闭包的结果。
var result1, result2, result3;
Q.all([
method1,
method2,
method3
]).spread(function(
promiseResult1,
promiseResult2,
promiseResult3
){
return doSomethingWhichReturnsPromise(promiseResult1)
.then(function() {
<do something with promiseResult2>
})
.catch(function() {
<do something with promiseResult3>
})
})
我最近开始为我的 Node.js 应用程序使用 q promise javascript 库。在我的代码中,我有一个条件来确定我是否应该执行 1 个或 3 个 promise 方法。然后我想执行返回承诺的方法数组并对结果执行额外的处理。
问题:如何使用内部和外部的结果.spread(...)
,以便将结果传递给其他方法?
一些背景:我正在构建一个 REST API,根据 POSTed JSON 正文的值,我必须首先使用 Sequelize 将记录插入数据库,得到响应(所以我知道自动生成的主键),然后使用该主键在其他 table 中插入记录。
var promiseMethods;
var someParam1, someParam2, someParam3 = 'Hello World';
if (someCondition == true) {
promiseMethods = [promiseMethod1(someParam1)];
} else {
promiseMethods = [
promiseMethod1(someParam1),
promiseMethod2(someParam2),
promiseMethod3(someParam3)];
}
Q.all(promiseMethods)
.spread(function(promseResult1,
promiseResult2,
promiseResult3) {
var model = {
result: promiseResult1
};
//Other code removed for brevity.
return DatabasePromise.save(model)
});
然后我希望能够执行类似以下假设代码的操作。
var result = add(promiseResult1)
var result2 = subtract(promiseResult2)
var result3 = multiply(promiseResult3)
基本上我想并行执行前 1 或 3 个返回承诺的方法,然后能够在之后多次使用承诺结果。
这里是我希望代码执行的更好的想法。这里的示例是我有一个产品 table,用户与该产品相关联。我想将数据插入这两个 table(以及第三个 table)。
var _ = require('lodash');
function insert(request, reply) {
var response;
var db = getDBConnection();
var step1Promises;
if (property == true) {
step1Promises = [
CommonModule.promiseMethodForProductUsers(db, userUUIDs)
];
} else {
step1Promises = [
CommonModule.promiseMethodForProductUsers(db, userUUIDs),
CommonModule.promiseMethod2(payload.data1, payload.data2),
CommonModule.promiseMethod3(db, payload.data3)
];
}
var step1 = Q.all(step1Promises);
var resolvedProductUsers;
var internalIDs;
var productPromise = step1.spread(function(productUsers, promiseMethod2, promiseMethod3) {
resolvedProductUsers = productUsers;
var currentUser = users[0].uid;
internalIDs = Q(_.pluck(resolvedProductUsers, 'uid'));
var product = db.Product.build({
product_name: productName,
last_edit_user_id: currentUser
});
return CommonModule.createProduct(db, product);
});
// When running, internalIDs is undefined.
var step2 = Q.all([
CommonModule.buildProductUsersModel(db, internalIDs, productPromise.tid),
CommonModule.buildOtherTableModel(db, productPromise.pid, currentUser.Id, otherData)
]);
step2.spread(function(usersToInsert, otherTableDataToInsert) {
CommonModule.saveProductUsers(db, usersToInsert);
CommonModule.saveOtherTableData(db, otherTableDataToInsert);
});
// The response must be a promise, otherwise this insert method will finish
// and return an empty result.
response = productPromise;
return reply(response);
}
您可以使用普通变量来缓存传播的结果以供进一步使用。
var result1, result2, result3;
Q.all([
method1,
method2,
method3
]).spread(function(
promiseResult1,
promiseResult2,
promiseResult3
){
result1 = promiseResult1;
result2 = promiseResult2;
result2 = promiseResult2;
...
<do something with result1>
}).then(function) {
// outside the spread
<do something with result2>
//
<do something with result3>
})
您还可以使用嵌套闭包来访问父闭包的结果。
var result1, result2, result3;
Q.all([
method1,
method2,
method3
]).spread(function(
promiseResult1,
promiseResult2,
promiseResult3
){
return doSomethingWhichReturnsPromise(promiseResult1)
.then(function() {
<do something with promiseResult2>
})
.catch(function() {
<do something with promiseResult3>
})
})