如何在 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>
  })
})