web-dev-qa-db-fra.com

Comment promettez-vous correctement la demande?

La promisifaction de Bluebird est un peu magique, et request est un vrai gâchis (c'est une fonction qui se comporte comme un objet avec des méthodes).

Le scénario spécifique est assez simple: j'ai une instance de demande avec les cookies activés, via un fichier cookie (n'utilisant pas le gestionnaire de cookies global de request). Comment puis-je le promettre efficacement et toutes les méthodes qu'il prend en charge?

Idéalement, j'aimerais pouvoir:

  • appeler request(url) -> Promise
  • appeler request.getAsync(url) -> Promise
  • appeler request.postAsync(url, {}) -> Promise

Il semble que Promise.promisifyAll(request) soit inefficace (car je reçois "postAsync n'est pas défini").

31
Madara Uchiha

Les éléments suivants devraient fonctionner:

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

Notez que cela signifie que request n'est pas une fonction gratuite car la promisification fonctionne avec des méthodes prototypes car this n'est pas connue à l'avance. Il ne fonctionnera que dans les versions plus récentes de bluebird. Répétez-le lorsque vous en avez besoin lorsque vous bifurquez l'objet de demande de cookies.


Si vous utilisez Bluebird v3, vous voudrez utiliser l'option multiArgs:

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

En effet, le rappel de la demande est (err, response, body): le comportement par défaut de Bluebird v3 est de ne prendre que le premier argument de valeur de succès (c'est-à-dire response) et d'ignorer les autres (c'est-à-dire body).

38
Benjamin Gruenbaum

vous pouvez utiliser le module request-promise .

Le client HTTP de renommée mondiale "Request" est désormais conforme à Promises/A +. Propulsé par Bluebird.

Installez le module et vous pouvez utiliser la demande dans le style de promesse.

npm install request-promise
33
Arvind Sridharan

Notez que vous n'avez pas besoin du troisième paramètre de rappel, body. Il est également présent sur le paramètre response. Si vous vérifiez la source vous pouvez voir que body est juste une commodité pour response.body. Ils sont garantis d'être toujours les mêmes.

Cela signifie que la simple promisification décrite dans les autres réponses de cette page est suffisante pour obtenir toutes les données de réponse.

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

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

Cela n'est vrai que pour le response passé au rappel/promesse. L'objet response passé à l'événement de réponse est un http.IncomingMessage et en tant que tel n'a pas de propriété body.

4
Tamlyn

Je donne un exemple, par util base sur Node.js v11.10.

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 
     });

Ou, en utilisant de manière équivalente async/await:

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