javascript - Node.js / Javascript 多重递归承诺在视图中返回
问题描述
我目前有一个具有多个递归调用的算法,我希望每个人都从中返回以巩固我的结果
问题是有太多的递归调用,我不再知道如何返回我的合并结果
我试图通过按结果数检查承诺的数量,在每个承诺的末尾做出一个 promise.all,但我得到的结果表明我正在做出几个 http 响应
在这个版本中,我在所有承诺执行或添加到我的承诺列表之前返回结果。
var https = require('https');
var moment = require('moment');
app.get('/detail/:issue', function (req, res) {
var promises = [];
var jsonResult = {
total: {
daysSpent: 0,
daysEstimated: 0,
daysRemaining: 0,
cost: 0
},
issues: {}
};
var getIssue = function (key) {
/**
* Récupération des imputations par projet.
*/
promises.push(new Promise(function (resolve) {
var options = Object.assign({}, app.locals.data.jira);
options.path = "/jira/rest/api/2/issue/{issueKey}"
.replace('{issueKey}', key);
https.request(options, (resp) => {
let body = '';
resp.on('data', (chunk) => {
body += chunk;
});
resp.on('end', () => {
var issue = JSON.parse(body);
if (issue.fields.issuetype.name == 'Epic') {
getEpic(issue.key);
} else {
jsonResult.issues[issue.key] = {
key: issue.key,
numberTicket: issue.fields.customfield_10267 === null ? "-" : issue.fields.customfield_10267,
icon: issue.fields.issuetype.iconUrl,
name: issue.fields.summary,
status: issue.fields.status.name,
daysEstimated: issue.fields.issuetype.subtask ? (((issue.fields.timeoriginalestimate || 0) / 3600) / 7) : ((issue.fields.customfield_11901 || 0) / 7),
daysRemaining: issue.fields.issuetype.subtask ? (((issue.fields.timeoriginalestimate || 0) / 3600) / 7) : ((issue.fields.customfield_11901 || 0) / 7),
hoursSpent: 0,
daysSpent: 0,
cost: 0,
parent: issue.fields.parent === undefined ? issue.key : issue.fields.parent.key,
detail: {},
subtask: issue.fields.issuetype.subtask,
worklog: issue.fields.worklog.total != 0
}
jsonResult.total.daysEstimated += ((issue.fields.customfield_11901 || 0) / 7);
jsonResult.total.daysRemaining += ((issue.fields.customfield_11901 || 0) / 7);
if (issue.fields.subtasks != false) {
for (let e in issue.fields.subtasks) {
e = issue.fields.subtasks[e];
getIssue(e.key);
};
}
if (issue.fields.worklog.total != 0) {
getWorklog(issue.key);
}
}
resolve();
});
}).on("error", (e) => {
console.log("Error: " + e.message);
}).end();
}));
}
var getEpic = function (key) {
/**
* Récupération des imputations par projet.
*/
promises.push(new Promise(function (resolve) {
var postData = JSON.stringify({
"jql": "'Epic link' = {issueKey}"
.replace('{issueKey}', key),
"maxResults": -1,
"fields": [
"issuekey"
]
});
var options = Object.assign({}, app.locals.data.jira);
options.path = "/jira/rest/api/2/search";
options.method = 'POST';
options.headers = {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
"Content-Length": Buffer.byteLength(postData)
};
var req = https.request(options, (resp) => {
let body = '';
resp.on('data', (chunk) => {
body += chunk;
});
resp.on('end', () => {
var issues = JSON.parse(body).issues;
for (let issue in JSON.parse(body).issues) {
issue = issues[issue];
getIssue(issue.key);
};
resolve();
});
}).on("error", (e) => {
console.log("Error: " + e.message);
});
req.write(postData);
req.end();
}));
}
var getWorklog = function (key) {
/**
* Récupération des imputations par projet.
*/
promises.push(new Promise(function (resolve) {
var options = Object.assign({}, app.locals.data.jira);
options.path = "/jira/rest/api/2/issue/{issueKey}/worklog"
.replace('{issueKey}', key);
https.request(options, (resp) => {
let body = '';
resp.on('data', (chunk) => {
body += chunk;
});
resp.on('end', () => {
var worklogs = JSON.parse(body).worklogs;
for (let e in worklogs) {
e = worklogs[e];
if (jsonResult.issues[key].detail[e.author.key] == undefined) {
jsonResult.issues[key].detail[e.author.key] = {
name: e.author.displayName,
hoursSpent: 0,
daysSpent: 0,
cost: 0
}
}
jsonResult.issues[key].hoursSpent += e.timeSpentSeconds / 3600;
jsonResult.issues[key].detail[e.author.key].hoursSpent += e.timeSpentSeconds / 3600;
if (app.locals.data.scr[moment(e.started).format("Y")] !== undefined && app.locals.data.scr[moment(e.started).format("Y")][e.author.emailAddress] !== undefined) {
var time = (e.timeSpentSeconds / 3600) / app.locals.data.scr[moment(e.started).format("Y")][e.author.emailAddress].modality;
var cost = time * app.locals.data.scr[moment(e.started).format("Y")][e.author.emailAddress].scr;
jsonResult.issues[key].detail[e.author.key].daysSpent += time;
jsonResult.issues[key].detail[e.author.key].cost += cost;
jsonResult.issues[key].daysSpent += time;
jsonResult.issues[key].cost += cost;
jsonResult.issues[key].daysRemaining -= time;
};
resolve();
});
}).on("error", (e) => {
console.log("Error: " + e.message);
}).end();
}));
}
getIssue(req.params.issue);
Promise.all(promises).then(function () {
res.json(jsonResult);
});
});
解决方案
我已经解决了我的问题!
var https = require('https');
var moment = require('moment');
app.get('/detail/:issue', function (req, res) {
var jsonResult = {
total: {
daysSpent: 0,
daysEstimated: 0,
daysRemaining: 0,
cost: 0
},
issues: {}
};
var getIssue = function (key) {
/**
* Récupération des imputations par projet.
*/
return new Promise(function (resolve) {
var options = Object.assign({}, app.locals.data.jira);
options.path = "/jira/rest/api/2/issue/{issueKey}"
.replace('{issueKey}', key);
https.request(options, (resp) => {
let body = '';
resp.on('data', (chunk) => {
body += chunk;
});
resp.on('end', () => {
var promises = [];
var issue = JSON.parse(body);
if (issue.fields.issuetype.name == 'Epic') {
promises.push(getEpic(issue.key));
} else {
jsonResult.issues[issue.key] = {
key: issue.key,
numberTicket: issue.fields.customfield_10267 === null ? "-" : issue.fields.customfield_10267,
icon: issue.fields.issuetype.iconUrl,
name: issue.fields.summary,
status: issue.fields.status.name,
daysEstimated: issue.fields.issuetype.subtask ? (((issue.fields.timeoriginalestimate || 0) / 3600) / 7) : ((issue.fields.customfield_11901 || 0) / 7),
daysRemaining: issue.fields.issuetype.subtask ? (((issue.fields.timeoriginalestimate || 0) / 3600) / 7) : ((issue.fields.customfield_11901 || 0) / 7),
hoursSpent: 0,
daysSpent: 0,
cost: 0,
parent: issue.fields.parent === undefined ? issue.key : issue.fields.parent.key,
detail: {},
subtask: issue.fields.issuetype.subtask,
worklog: issue.fields.worklog.total != 0
}
jsonResult.total.daysEstimated += ((issue.fields.customfield_11901 || 0) / 7);
jsonResult.total.daysRemaining += ((issue.fields.customfield_11901 || 0) / 7);
if (issue.fields.worklog.total != 0) {
promises.push(getWorklog(issue.key));
}
if (issue.fields.subtasks != false) {
for (let e in issue.fields.subtasks) {
e = issue.fields.subtasks[e];
promises.push(getIssue(e.key));
};
}
}
Promise.all(promises).then(function () {
resolve();
});
});
}).on("error", (e) => {
console.log("Error: " + e.message);
}).end();
});
}
var getEpic = function (key) {
/**
* Récupération des imputations par projet.
*/
return new Promise(function (resolve) {
var postData = JSON.stringify({
"jql": "'Epic link' = {issueKey}"
.replace('{issueKey}', key),
"maxResults": -1,
"fields": [
"issuekey"
]
});
var options = Object.assign({}, app.locals.data.jira);
options.path = "/jira/rest/api/2/search";
options.method = 'POST';
options.headers = {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
"Content-Length": Buffer.byteLength(postData)
};
var req = https.request(options, (resp) => {
let body = '';
resp.on('data', (chunk) => {
body += chunk;
});
resp.on('end', () => {
var promises = [];
var issues = JSON.parse(body).issues;
for (let issue in JSON.parse(body).issues) {
issue = issues[issue];
promises.push(getIssue(issue.key));
};
Promise.all(promises).then(function () {
resolve();
});
});
}).on("error", (e) => {
console.log("Error: " + e.message);
});
req.write(postData);
req.end();
});
}
var getWorklog = function (key) {
/**
* Récupération des imputations par projet.
*/
return new Promise(function (resolve) {
var options = Object.assign({}, app.locals.data.jira);
options.path = "/jira/rest/api/2/issue/{issueKey}/worklog"
.replace('{issueKey}', key);
https.request(options, (resp) => {
let body = '';
resp.on('data', (chunk) => {
body += chunk;
});
resp.on('end', () => {
var worklogs = JSON.parse(body).worklogs;
for (let e in worklogs) {
e = worklogs[e];
if (jsonResult.issues[key].detail[e.author.key] == undefined) {
jsonResult.issues[key].detail[e.author.key] = {
name: e.author.displayName,
hoursSpent: 0,
daysSpent: 0,
cost: 0
}
}
jsonResult.issues[key].hoursSpent += e.timeSpentSeconds / 3600;
jsonResult.issues[key].detail[e.author.key].hoursSpent += e.timeSpentSeconds / 3600;
if (app.locals.data.scr[moment(e.started).format("Y")] !== undefined && app.locals.data.scr[moment(e.started).format("Y")][e.author.emailAddress] !== undefined) {
var time = (e.timeSpentSeconds / 3600) / app.locals.data.scr[moment(e.started).format("Y")][e.author.emailAddress].modality;
var cost = time * app.locals.data.scr[moment(e.started).format("Y")][e.author.emailAddress].scr;
jsonResult.issues[key].detail[e.author.key].daysSpent += time;
jsonResult.issues[key].detail[e.author.key].cost += cost;
jsonResult.issues[key].daysSpent += time;
jsonResult.issues[key].cost += cost;
jsonResult.issues[key].daysRemaining -= time;
if (jsonResult.issues[key].subtask) {
jsonResult.issues[jsonResult.issues[key].parent].hoursSpent += e.timeSpentSeconds / 3600;
jsonResult.issues[jsonResult.issues[key].parent].daysSpent += time;
jsonResult.issues[jsonResult.issues[key].parent].cost += cost;
jsonResult.issues[jsonResult.issues[key].parent].daysRemaining -= time;
}
jsonResult.total.daysSpent += time;
jsonResult.total.cost += cost;
jsonResult.total.daysRemaining -= time;
}
};
resolve();
});
}).on("error", (e) => {
console.log("Error: " + e.message);
}).end();
});
}
getIssue(req.params.issue).then(function () {
res.json(jsonResult);
});
});
每个方法都等待其所有子方法结束才能得出结论
推荐阅读
- github - Jekyll Github Actions 管道卡在 jekyll build
- r - 热图生成R中的cut.default错误
- c++ - Visual Studio C++ std::istream::read 文件打开失败
- c - *pe=pn->Entry; 的作用是什么?
- c++ - 字符串解析器函数未正确写入元组
- django - Django 身份验证权限
- r - 如何使用一列来选择 r 中另一列的行?
- python - TDAmeritrade API 获取用户位置
- testng - 如何在 Cypress 中添加测试用例分组
- github-actions - 我应该使用 MarketPlace 操作而不是普通的 bash `cp` 命令来复制文件吗?