在Promises和函数之间传递变量

时间:2017-09-14 07:52:46

标签: javascript node.js promise

我有问题。 我必须做两个不同的SOAP调用来检索两个凭证列表,然后使用这些列表来检查它们并完成一些工作。 我把两个调用放在不同的Promise函数中,因为我希望在调用返回结果后在列表上启动作业。 这是第一个Promise电话:

    let vouchers = function(voucherTypeList){
  return new Promise(function(resolve,reject){
    const categoryId = "1000";
    let args = {
      "tns:CategoryId": categoryId
    };
    var header = {
      "tns:Authenticate": {
        "tns:UserName": soapVoucherWsdlUsername,
        "tns:Password": soapVoucherWsdlPassword
      }
    };

    // let voucherTypeList;
    voucherClient.addSoapHeader(header);
    voucherClient.GetVouchers(args, function(err, result) {
      console.log("DENTRO GET VOUCHERS");
      if (err) {
        console.log(err);
        writeResponse(res, '200', err);
      } else {
        //++++++++++++++++++++++
        //voucherTypeList is what I want to return to the main function
        voucherTypeList = mapGetVoucherTypeListResponse(result);
        //++++++++++++++++++++++
      }
      resolve("done 1");
    });
  });
}

这是第二个Promise电话:

let issuedVouchers = function(accountId) {
  return new Promise(function (resolve, reject) {
    const categoryId = "1000";
    let args = {
      "tns:CategoryId": categoryId,
      "tns:CheckRedeem": true,
      "tns:IncludeRedeemed": false,
      "tns:CardId": accountId
    };
    var header = {
      "tns:Authenticate": {
        "tns:UserName": soapVoucherWsdlUsername,
        "tns:Password": soapVoucherWsdlPassword
      }
    };

    let issuedVoucherList;
    voucherClient.addSoapHeader(header);
    voucherClient.GetVouchers(args, function (err, result) {
      console.log("DENTRO GET ISSUED VOUCHERS");
      if (err) {
        console.log(err);
        writeResponse(res, '200', err);
      } else {
        //++++++++++++++++++++++
        //issuedTypeList is what I want to return to the main function
        issuedTypeList = mapGetVoucherTypeListResponse(result);
        //++++++++++++++++++++++    
      }
      resolve("done 2");
    });


  });
}

这是主要功能,Promise流程:

function getAvailableVoucherTypes(req, res) {
  var accountId = req.params.accountId;
vouchers(voucherTypeList).
    then(issuedVouchers(accountId)).
        then(function() {
        //here I want to use voucherTypeList and issuedTypeList
        //and do some jobs on them
        console.log("OK");
        });
}

我该怎么做?我尝试了很多解决方案,但是我无法在主函数中看到 voucherTypeList issuedTypeList

1 个答案:

答案 0 :(得分:1)

then回调获得您在承诺中传递给resolve函数的值。您当前正在传递任意字符串,这是无用的......但是对于演示,请保留这些字符串并将其值记录在主脚本中:

function getAvailableVoucherTypes(req, res) {
  var accountId = req.params.accountId;
vouchers(voucherTypeList).
    then(function(result){
         console.log(result); //done 1
         return issuedVouchers(accountId);
    }).
        then(function(result) {
          console.log(result); //done 2
        //here I want to use voucherTypeList and issuedTypeList
        //and do some jobs on them
        console.log("OK");
        });
}

我会让你发挥你的承诺,传递正确的变量......

现在,看来你的2个电话不需要是连续的,所以让它们并行,对我们来说也会稍微容易一点。

function getAvailableVoucherTypes(req, res) {
  var accountId = req.params.accountId;
  var promises = [vouchers(),issuedVouchers(accountId)]
  Promise.all(promises).then(function(results){
      //In Promise.all, the results of each promise are passed as array
      //the order is the same as the order of the promises array.
      var voucherTypeList = results[0];
      var issuedTypeList = results[1];
  });
}

奖励:在你正确掌握之前,我不想太过复杂化这个任务。所以我不会添加更多代码。但请注意,您也应该使用拒绝,而不是在每个承诺中处理您的错误,您应该在出现问题时拒绝它们。只需reject(err)并向主脚本添加第二个回调即可处理可能发生的任何错误。如果您继续解决不起作用的承诺,您将不会传递您期望的元素,并且您需要在每个步骤中添加检查。

让我们修改GetVouchers回调以符合我的建议。

voucherClient.GetVouchers(args, function (err, result) {
  console.log("DENTRO GET ISSUED VOUCHERS");
  if (err) {
    reject(err);
  } else {
    resolve(mapGetVoucherTypeListResponse(result));  
  }
});

在您的承诺完成后,我们可以更改您的主脚本以相应地处理错误。

Promise.all(promises).then(function(results){
   //Handle success like above.
},function(err){
   //Handle error.
    console.log(err.stack || err);
    writeResponse(res, '200', err);
});