(Nodejs + Restify)发送后不能设置标头 - 承诺拒绝警告

时间:2017-11-14 06:04:50

标签: javascript node.js promise restify

UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):错误:发送后无法设置标头。 当我在请求完成之前连续点击API或再次点击API时会发生此错误。 提到了许多解决方案,但无法得到正确的答案。请帮助我理清。

exports.getRecords = function(req, res) {

        db.task(t => {
                return t.batch([
                    t.any(selectQuery),
                    t.any(recordCountQuery)
                ]);
            })
            .then(data => {

                //create a formatted object based on the two queries with recordCount
                var output = {};

                output.meta = data[1][0];
                let petData = data[0];

                /*
                 * Checks If the pet details available and then processing the pets Data
                 * To get the existing image URL.
                 */

                if (!util.isNullOrUndefined(petData)) {
                    //Iterating over the Array of pets and process each pets with promises()
                    Promise.all(petData.map(pet => {

                            //Processing each pet
                            return processUtil.getvalidData(pet)
                                .then(pet => pet);
                        }))
                        .then(results => {
                            //After processing all the pets send the output
                            output.data = results;
                            res.json(output);
                        })
                };
            })
            .catch(function(err) {
                if (util.isError(err)) {
                    res.error('NotFoundError', err);
                } // return 404
                else {
                    res.error('InternalServerError', err);
                }; //else 500

            });
    };

以下是两个回复的控制台日志

单击

的响应日志
    "15" "TRACE" "services-data" "lynd-PC" "sr"  "4596ec40" "" "GET" "/data/2" "request received"
    "16" "TRACE" "services-data" "lynd-PC" ""    "4596ec40" "" "GET" "/data/2" ""
    "17" "TRACE" "services-data" "lynd-PC" ""    "4596ec40" "" "GET" "/data/2" ""
    "18" "TRACE" "services-data" "lynd-PC" "ss"  "4596ec40" "200" "GET" "/data/2" "response sent"

在我们在请求完成之前两次点击API时的响应日志。

"15" "TRACE" "services-data" "lynd-PC" "sr"  "1a85afb7" "" "GET" "/data/2" "request received"
"15" "TRACE" "services-data" "lynd-PC" ""    "1a85afb7" "" "GET" "/data/2" ""
"16" "TRACE" "services-data" "lynd-PC" ""    "1a85afb7" "" "GET" "/data/2" ""
"17" "TRACE" "services-data" "lynd-PC" "ss"  "1a85afb7" "500" "GET" "/data/2" "response sent"
"18" "TRACE" "services-data" "lynd-PC" ""    "1a85afb7" "" "GET" "/data/2" ""
(node:3860) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Can't set headers after they are sent.

1 个答案:

答案 0 :(得分:1)

对于初学者,代码中的Promise.all()没有拒绝处理程序。您可以通过更改此链接将其链接到父承诺链(它具有拒绝处理程序):

Promise.all(petData.map(pet => {

到此:

return Promise.all(petData.map(pet => {

因此,这将为未经处理的拒绝提供一个机会。或者,如果您希望为其设置单独的拒绝处理程序,则可以将自己的拒绝句柄添加到Promise.all()承诺中。

您似乎还有几个不会发送任何响应的代码路径。如果这个条件:

if (!util.isNullOrUndefined(petData)) {

不满意(意味着它不会进入if块),那么您的代码将不会发送任何通常是编码错误的响应,因为每个请求只需要发送一个响应。