Javascript Node.js处理来自链接承诺的响应

Javascript Node.js处理来自链接承诺的响应,javascript,node.js,promise,Javascript,Node.js,Promise,我有3个函数,每个函数都返回一个承诺。如何将每个承诺的响应分配给定义的对象 这是我的代码: const runResponse = { webAudits: [], webJourneys: [], appJourneys: [] }; webAuditsFailures(req) .then( appJourneysFailures(req) ) .then( webJourneysFailures(req) ).then(

我有3个函数,每个函数都返回一个承诺。如何将每个承诺的响应分配给定义的对象

这是我的代码:

  const runResponse = {
    webAudits: [],
    webJourneys: [],
    appJourneys: []
  };

  webAuditsFailures(req)
  .then(
    appJourneysFailures(req)
  )
  .then(
    webJourneysFailures(req)
  ).then(
    res.status(201).json({ reports: runResponse })
  );
这就是我尝试过的:

webAuditsFailures(req)
  .then(
    (response) => {
      runResponse.webAudits = response
    },
    appJourneysFailures(req)
  )
  .then(
    (response) => {
      runResponse.appJourneys = response
    },
    webJourneysFailures(req)
  ).then(
    (response) => {
      runResponse.webJourneys = response
    },
    res.status(201).json({ reports: runResponse })
  );
但是它没有像预期的那样工作,因为
webAuditsFailures
被再次调用,即使它没有结束,我也不明白为什么

以下是修复此问题的其他失败尝试:

使用
wait

  const webAudits = await webAuditsFailures(req);
  const appJourneys = await appJourneysFailures(req);
  const webJourneys = await webJourneysFailures(req);

  runResponse.webAudits = webAudits;
  runResponse.webJourneys = webJourneys;
  runResponse.appJourneys = appJourneys;
同样的事情也发生在这件事上:

 const webAudits = await webAuditsFailures(req);
 runResponse.webAudits = webAudits;
使用
co
模块:

  co(function* () {
    var runResponse = yield {
      webAudits: webAuditsFailures(req),
      webJourneys: appJourneysFailures(req),
      appJourneys: webJourneysFailures(req)
    };
    res.status(201).json({ reports: runResponse });
  });
使用
承诺。所有

Promise.all([webAuditsFailures(req), appJourneysFailures(req),
  webJourneysFailures(req)])
    .then(function(allData) {
      res.status(201).json({ reports: allData });
  });
这是
webAuditsFailures
函数,它依次调用另一个返回承诺的函数

export default async (req) => {
  const report = req.body.webAudits;
  const def = deferred();

  if(report.length > 0) {
    var reportList = [];
    for(const [reportIndex, item] of report.entries()) {
      for(const [runIndex, run] of item.runs.entries()) {
        const result = await waComplianceBusiness(req, run.id);
        var failureList = [];
        if(result.data.overviews) {
          const compliance = result.data.overviews[0].compliance;
          if(compliance) {
            for(const [index, rule] of compliance.entries()) {
              const response = await waRuleOverview(req, run.id, rule.id);
              const failedConditions = response.data.failedConditions;
              const ruleName = response.data.ruleName;

              if(response.data.pagesFailed > 0) {
                for(const [condIndex, condition] of failedConditions.entries()) {
                  const request = {
                    itemId: condition.conditionResult.id,
                    itemType: condition.conditionResult.idType,
                    parentId: condition.conditionResult.parentId,
                    parentType: condition.conditionResult.parentType
                  }
                  const body = {
                    runId: run.id,
                    ruleId: rule.id,
                    payload: request
                  }

                  waConditionOverview(req, body).done(response => {
                    // do stuff here
                  });
                }
              }
            }
            if(failureList.length > 0) {
              item.runs[runIndex].failures = failureList;
            }
          }
        }
      }
    }
    def.resolve(report);
    return def.promise
  }
  else {
    return [];
  }
}

在承诺链中,当前的
.then()
应该返回一个承诺。此承诺的结果将传递给下一个
。然后()

根据上一个
.json()
.then()
所做的操作,如果承诺链中有其他
.then()
的话,您也应该返回它。

这就是问题所在:

waConditionOverview(req, body).done(response => {
  // do stuff here
});
您正在执行异步操作,但不等待结果。不要使用延迟模型-使用
util.promisify
进行回调

此外,我强烈建议不要像这样修改请求/响应,而是将信息存储在对象中并返回它们

下面是如何编写代码:

export default async (req) => {
  const report = req.body.webAudits;  
  if(report.length === 0) return;
  const runs = Array.from(report.entries(), ([i, item]) => item.runs.entries());
  for (const [_, run] of runs) {
    const result = await waComplianceBusiness(req, run.id);
    var failureList = [];
    if (!result.data.overviews) {
      continue;
    }
    const compliance = result.data.overviews[0].compliance;
    if(!compliance) {
      continue;
    }
    for(const [_, rule] of compliance.entries()) {
      const response = await waRuleOverview(req, run.id, rule.id);
      const { failedConditions, ruleName} = response.data;

      if(failureList.length > 0) {
        item.runs[runIndex].failures = failureList;
      }
      if(response.data.pagesFailed === 0) continue;

      for(const [_, condition] of failedConditions.entries()) {
        const request = {
          itemId: condition.conditionResult.id,
          itemType: condition.conditionResult.idType,
          parentId: condition.conditionResult.parentId,
          parentType: condition.conditionResult.parentType
        }
        const body = { runId: run.id, ruleId: rule.id, payload: request}
        const reponse = await waConditionOverview(req, body);
        // do stuff here
        // update response
        // update report, so next time we try it's updated and doesn't return empty;
      }
    }
  }
  return report;
}

你能发布webAuditsFailures()函数并解释需要什么吗?@MarioSantini更新了这个问题。Req是路由请求什么是
延迟()
,为什么不使用
新承诺()
?您还返回了一个
[]
def.promise
,这可能会使调用代码混淆。您可能希望使用一种返回类型。@styfle Deferred是一个节点模块。。。我不使用
newpromise()
,因为我不知道如何在我的代码中实现它,也许我得到了它。您的函数被标记为async,这将在调用该函数时返回一个承诺。这意味着如果不使用wait,代码将继续运行而不是等待。因为它希望您处理承诺,就像您实现.then()部分一样。使用这种方法会导致相同的问题…函数
webAuditsFailures
会再次被调用,即使它没有返回任何东西。这工作很好,但是如果我尝试使用wait调用我的所有3个函数(
const webAudits=wait webAuditsFailures(req);const appJourneys=wait appJourneysFailures(req);const webJourneys=wait webJourneysFailures(req);
)然后它将重新调用第一个函数(webAuditsFailures)就在它返回一个响应并且不等待其他两个函数完成之后…它为什么这样做?基本上它是这样做的:调用
webAuditsFailures
,为它返回响应,调用
appJourneysFailures
,调用
webAuditsFailures
,返回
appJourneysFailures
webAuditsFailures
仍在运行),调用
webJourneysFailures
,返回对它的响应,再次返回对
webAuditsFailures
的响应,然后再次调用
appJourneysFailures
webJourneysFailures
函数……希望这能让您更好地理解问题。我发现问题不是
webAuditsFailures
功能,因为每次都会在2分钟后重新调用路由(如果post请求不到2分钟,则没有问题)。我在这里发布了一个新问题
export default async (req) => {
  const report = req.body.webAudits;  
  if(report.length === 0) return;
  const runs = Array.from(report.entries(), ([i, item]) => item.runs.entries());
  for (const [_, run] of runs) {
    const result = await waComplianceBusiness(req, run.id);
    var failureList = [];
    if (!result.data.overviews) {
      continue;
    }
    const compliance = result.data.overviews[0].compliance;
    if(!compliance) {
      continue;
    }
    for(const [_, rule] of compliance.entries()) {
      const response = await waRuleOverview(req, run.id, rule.id);
      const { failedConditions, ruleName} = response.data;

      if(failureList.length > 0) {
        item.runs[runIndex].failures = failureList;
      }
      if(response.data.pagesFailed === 0) continue;

      for(const [_, condition] of failedConditions.entries()) {
        const request = {
          itemId: condition.conditionResult.id,
          itemType: condition.conditionResult.idType,
          parentId: condition.conditionResult.parentId,
          parentType: condition.conditionResult.parentType
        }
        const body = { runId: run.id, ruleId: rule.id, payload: request}
        const reponse = await waConditionOverview(req, body);
        // do stuff here
        // update response
        // update report, so next time we try it's updated and doesn't return empty;
      }
    }
  }
  return report;
}