你如何正确地承诺请求?

How do you properly promisify request?

提问人:Madara's Ghost 提问时间:2/4/2015 更新时间:10/25/2019 访问量:39324

问:

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)

JavaScript 承诺 蓝鸟

评论

0赞 idbehold 2/4/2015
完全披露,我是作者:http-as-promised
8赞 Benjamin Gruenbaum 2/4/2015
@idbehold,如果你要对事情说些什么,你只需要披露一些事情:P
0赞 Benjamin Gruenbaum 2/4/2015
这不是微不足道的,请考虑在问题跟踪器上提出问题。
0赞 Esailija 2/4/2015
不和 ?为什么两者都需要?request(...)request.get(...)
0赞 Madara's Ghost 2/4/2015
@Esailija我想是这样,但这主要是为了避免混淆。我想关键是所有的 API 都是有希望的,而且我没有因为没有意识到我需要它而挂起回调。严格来说,是的。两者之一是可选的。

答:

37赞 Benjamin Gruenbaum 2/4/2015 #1

以下方法应该有效:

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

请注意,这意味着这不是一个自由函数,因为 promisification 适用于原型方法,因为事先不知道。它仅适用于较新版本的 bluebird。在分叉 cookie 的请求对象时,在需要时重复此操作。requestthis


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

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

这是因为 request 的回调是: Bluebird v3 的默认行为是只取第一个成功值参数(即 ),而忽略其他参数(即)。(err, response, body)responsebody

评论

1赞 Madara's Ghost 2/4/2015
它如何与 的 cookie 一起使用?因为据我所知,它创建了一个带有 cookie jar 的新实例requestrequest
0赞 Benjamin Gruenbaum 2/26/2015
@SecondRikudo它现在可以在新的蓝鸟中使用。请查看:)
1赞 dopatraman 6/18/2015
当您说“较新版本”时,具体是哪个版本?
1赞 jfriend00 12/15/2016
Bluebird 的 promisification 与发送到回调的 and 参数有什么关系?它是否忽略了正文,只使用参数作为承诺的解析值?responsebodyrequest.get()response
0赞 Benjamin Gruenbaum 3/11/2017
@Retsam这只是答案的一部分。{multiArgs: true}
33赞 Arvind Sridharan 9/3/2015 #2

您可以使用 request-promise 模块。

举世闻名的 HTTP 客户端“Request”现在符合 Promises/A+ 标准。 由Bluebird提供支持。

安装该模块,您可以在 promise 样式中使用 request。

npm install request-promise

评论

0赞 Cmag 9/30/2017
nit:没有 .tapCatch 或其他 bluebird 方法
0赞 kper 11/29/2017
它使用的不是最新版本的蓝鸟
9赞 Little Roys 2/27/2019 #3

我举个例子,基于 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
}

评论

0赞 Madara's Ghost 2/27/2019
请注意,最初的问题是关于对象的具体问题,而不是它的任何方法,这些方法(相对)容易。request
11赞 Tamlyn 3/28/2019 #4

请注意,您不需要第三个回调参数 .它也存在于参数上。如果你检查来源,你会发现这只是一个方便。它们保证始终相同。bodyresponsebodyresponse.body

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

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

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

这仅适用于传递给回调/承诺的内容。传递给响应事件的对象是标准的,因此没有属性。responseresponsehttp.IncomingMessagebody