javascript - Node.js 处理来自链式 promise 的响应

标签 javascript node.js promise

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

这是我的代码:

  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 被再次调用,即使它没有结束,我不明白为什么...

这些是解决此问题的其他失败尝试:

使用await

  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:

Promise.all([webAuditsFailures(req), appJourneysFailures(req),
  webJourneysFailures(req)])
    .then(function(allData) {
      res.status(201).json({ reports: allData });
  });

这是 webAuditsFailures 函数,它依次调用另一个返回 promise 的函数

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 [];
  }
}

最佳答案

问题是:

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;
}

关于javascript - Node.js 处理来自链式 promise 的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45674613/

相关文章:

javascript - 链接 promise 链

promise - thunk、futures 和 Promise 之间有什么区别?

javascript - 如何在点击时运行事件加载?

javascript - Axios 方法将 item 作为 null 传递,而不是将实际值传递给我的 mongoose 路由

node.js - 类型错误 : undefined is not a function in nodejs

javascript - Nodejs - 如何将数据从 html 发送到 hapi

javascript - 如何让 javascript 为 Node 中的事件队列提供服务

javascript - if 语句中的 Eval()

javascript - 代码在运行 Node 控制台时有效,但在调用 Node <app_name.js> 时无效

node.js - 为什么重音字母在express.js 中不能正确解释?