承诺等待超时

promise await timeout exceeded

我在异步函数中得到了以下代码。 当我调用该函数时,我在 await 语句之后卡住了。 我已经检查了我的 nock 地址以获取 http req mocking,它与请求中的相同。

        await new Promise((resolve) => {
            let req = http.request(reqUrl, function (res) {
                console.info('Start http GET request');
                var responseBody = '';
                res.setEncoding('utf8');
                // Read the response body
                res.on('data', function (data) {
                    responseBody = data;
                });
                res.on('end', function () {
                    console.info('feature toggle response code ' + res.statusCode);
                    if (res.statusCode === 200) {
                        if (responseBody.trim() != '') {
                            if (responseBody === 'true') {
                                console.info('feature toggle is on');
                                self.evolveData.getByAttribute = self.evolveData.getByAttributeLimited;
                            } else {
                                console.info('feature toggle is off');
                            }
                        }
                    } else {
                        printErrorMessage('fail message', res, responseBody);
                        self.context.fail(responseBody);
                    }
                    resolve();
                });
                req.on('error', function () {
                    self.context.fail(responseBody);
                    resolve();
                });
            });
        });

当你使用http.request()时,你必须调用req.end()才能真正发起请求并发送。请注意,如果您切换到 http.get(),则不必调用 req.end(),因为 http.get() 会为您完成。

这是一个演示的独立程序:

const http = require('http');

async function run() {
    await new Promise((resolve) => {
        let req = http.request("http://www.google.com", function (res) {
            console.log('Start http GET request');
            var responseBody = '';
            res.setEncoding('utf8');
            // Read the response body
            res.on('data', function (data) {
                responseBody += data;
            });
            res.on('end', function () {
                console.info('feature toggle response code ' + res.statusCode);
                if (res.statusCode === 200) {
                    console.log("got 200 response")
                }
                resolve();
            });
        });
        req.on('error', function () {
            console.log("error");
            resolve();
        });
        req.end();               // <=== You were missing this
    });
    console.log("after await");
}

run();

如果您删除了 req.end(),那么它就像在您的代码中一样丢失了,您会得到同样的结果。承诺永远不会解决,因为请求永远不会发送。


此外,为了完整起见,请注意 req.on('error', ...) 需要处于更高级别(在 http.request() 回调之外),以便您可以在调用回调之前获得可能发生的错误,或者在由于错误而未调用回调的情况下。


仅供参考,几个文档参考:

来自 doc for http.request():

With http.request() one must always call req.end() to signify the end of the request - even if there is no data being written to the request body.

来自 doc for http.get():

The only difference between this method and http.request() is that it sets the method to GET and calls req.end() automatically.