提问人:Madara's Ghost 提问时间:2/4/2015 更新时间:10/25/2019 访问量:39324
你如何正确地承诺请求?
How do you properly promisify request?
问:
Bluebird promisifaction 有点神奇,而且很混乱(它是一个带有方法的对象的函数)。request
具体场景非常简单:我有一个启用了 cookie 的请求实例,通过 cookie jar(不使用 的全局 cookie 处理程序)。我怎样才能有效地承诺它,以及它支持的所有方法?request
理想情况下,我希望能够:
- call -> 承诺
request(url)
- call -> 承诺
request.getAsync(url)
- call -> 承诺
request.postAsync(url, {})
这似乎是无效的(因为我得到“postAsync is not defined”)。Promise.promisifyAll(request)
答:
以下方法应该有效:
var request = Promise.promisify(require("request"));
Promise.promisifyAll(request);
请注意,这意味着这不是一个自由函数,因为 promisification 适用于原型方法,因为事先不知道。它仅适用于较新版本的 bluebird。在分叉 cookie 的请求对象时,在需要时重复此操作。request
this
如果您使用的是 Bluebird v3,则需要使用以下选项:multiArgs
var request = Promise.promisify(require("request"), {multiArgs: true});
Promise.promisifyAll(request, {multiArgs: true})
这是因为 request 的回调是: Bluebird v3 的默认行为是只取第一个成功值参数(即 ),而忽略其他参数(即)。(err, response, body)
response
body
评论
request
request
response
body
request.get()
response
{multiArgs: true}
您可以使用 request-promise 模块。
举世闻名的 HTTP 客户端“Request”现在符合 Promises/A+ 标准。 由Bluebird提供支持。
安装该模块,您可以在 promise 样式中使用 request。
npm install request-promise
评论
我举个例子,基于 Node.js v11.10.0util
import { get, post } from "request";
import { promisify } from "util";
const [getAsync, postAsync] = [get, post].map(promisify);
getAsync("http://stackoverflow.com")
.then(({statusCode, body}) => {
//do something
});
或者,等效地使用:async/await
const foo = async () => {
const {statusCode, body} = await getAsync("http://stackoverflow.com")
// do something
}
评论
request
请注意,您不需要第三个回调参数 .它也存在于参数上。如果你检查来源,你会发现这只是一个方便。它们保证始终相同。body
response
body
response.body
这意味着本页其他答案中描述的简单承诺就足以获得所有响应数据。
const request = require('request')
const { promisify } = require('util')
const rp = promisify(request)
rp('https://example.com').then(({body, statusCode}) => ...)
这仅适用于传递给回调/承诺的内容。传递给响应事件的对象是标准的,因此没有属性。response
response
http.IncomingMessage
body
评论
request(...)
request.get(...)