简体   繁体   中英

Node.js / Javascript multiple recursive promise to return at view

I currently have an algorithm with multiple recursive calls from which I expect everyone to return in order to consolidate my result

The problem is that there are so many recursive calls that I no longer see how to return my consolidated result

I tried to make a promise.all at the end of each promise by checking the number of promises by the number of results, but I got a result indicating that I was making several http responses

With this version, I return the result before all my promises are executed or added to my promise list.

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

});

I have resolve my problem !

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

});

each method waits for all its sub-methods to end in order to conclude

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM