Подтвердить что ты не робот

Как вы должным образом обещаете запрос?

Продвижение Bluebird - немного волшебство, а request - довольно беспорядок (это функция, которая ведет себя как объект со способами).

Конкретный сценарий довольно прост: у меня есть экземпляр запроса с включенными cookie через банку cookie (не используя request global cookie handler). Как я могу эффективно обещать его и все методы, которые он поддерживает?

В идеале я хотел бы иметь возможность:

  • вызов request(url) → Обещание
  • вызов request.getAsync(url) → Обещание
  • вызов request.postAsync(url, {}) → Обещание

Кажется, что Promise.promisifyAll(request) неэффективен (поскольку я получаю "postAsync не определен" ).

4b9b3361

Ответ 1

Следующее должно работать:

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

Обратите внимание, что это означает, что request не является свободной функцией, так как promisification работает с прототипами, так как this не известно заранее. Он будет работать только в более новых версиях bluebird. Повторите это, когда вам нужно, когда вы накладываете объект запроса на файлы cookie.


Если вы используете Bluebird v3, вам нужно использовать опцию multiArgs:

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

Это связано с тем, что обратный вызов для запроса (err, response, body): поведение Bluebird v3 по умолчанию должно принимать только первый аргумент значения успеха (т.е. response) и игнорировать другие (т.е. body).

Ответ 2

вы можете использовать модуль request-promise.

Всемирно известный HTTP-клиент "Запрос" теперь Promises/A+. Работает на Bluebird.

Установите модуль, и вы можете использовать запрос в стиле обещаний.

npm install request-promise

Ответ 3

Я приведу пример, с помощью util базы на Node.js v11.10.0

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
}

Ответ 4

Обратите внимание, что вам не нужен третий параметр обратного вызова, 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.