你如何正确地承诺请求?

How do you properly promisify request?

Bluebird promisifaction 有点神奇,而 request 相当混乱(它是一个函数,其行为类似于具有方法的对象)。

具体情况非常简单:我有一个启用了 cookie 的请求实例,通过 cookie jar(不使用 request 的全局 cookie 处理程序)。我怎样才能有效地承诺它,以及它支持的所有方法?

理想情况下,我希望能够:

似乎 Promise.promisifyAll(request) 无效(因为我得到 "postAsync is not defined")。

以下应该有效:

var request = Promise.promisify(require("request"));
Promise.promisifyAll(request);

请注意,这意味着 request 不是一个自由函数,因为 promisification 与原型方法一起工作,因为 this 是事先不知道的。它只适用于较新版本的蓝鸟。当你需要为 cookie 分叉请求对象时重复它。


如果您使用的是 Bluebird v3,则需要使用 multiArgs 选项:

var request = Promise.promisify(require("request"), {multiArgs: true});
Promise.promisifyAll(request, {multiArgs: true})

这是因为请求的回调是 (err, response, body):Bluebird v3 的默认行为是仅采用第一个成功值参数(即 response)并忽略其他参数(即 body).

您可以使用 request-promise 模块。

The world-famous HTTP client "Request" now Promises/A+ compliant. Powered by Bluebird.

安装模块,即可使用promise风格的request

npm install request-promise

我举个例子,util基于Node.jsv11.10.0

import { get, post } from "request";
import { promisify } from "util";

const [getAsync, postAsync] = [get, post].map(promisify);


getAsync("http://whosebug.com")
    .then(({statusCode, body}) => { 
       //do something 
     });

或者,等效地使用 async/await

const foo = async () => {
    const {statusCode, body} = await getAsync("http://whosebug.com")
    // do something
}

请注意,您不需要第三个回调参数,body。它也出现在 response 参数中。如果你 check the source 你可以看到 body 只是 response.body 的一个方便。它们保证始终相同。

这意味着本页其他答案中描述的简单承诺足以获取所有响应数据。

const request = require('request')
const { promisify } = require('util')
const rp = promisify(request)

rp('https://example.com').then(({body, statusCode}) => ...)

这仅适用于传递给 callback/promise 的 response。传递给响应 事件 response 对象是标准 http.IncomingMessage,因此没有 body 属性.