Javascript Node.js处理来自链接承诺的响应
我有3个函数,每个函数都返回一个承诺。如何将每个承诺的响应分配给定义的对象 这是我的代码: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(
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;
}