web-dev-qa-db-fra.com

Comment attendre et retourner le résultat d'un http.request (), pour que plusieurs requêtes s'exécutent en série?

Supposons qu'il existe une fonction doRequest(options), qui est censée effectuer une requête HTTP et utilise http.request() pour cela.

Si doRequest() est appelé dans une boucle, je veux que la prochaine requête soit faite après la précédente (exécution en série, l'une après l'autre). Afin de ne pas jouer avec les rappels et les promesses, je veux utiliser le modèle async/attente (transpilé avec Babel.js pour fonctionner avec Node 6+).

Cependant, il n'est pas clair pour moi, comment attendre l'objet de réponse pour un traitement ultérieur et comment le renvoyer à la suite de doRequest():

var doRequest = async function (options) {

    var req = await http.request(options);

    // do we need "await" here somehow?
    req.on('response', res => {
        console.log('response received');
        return res.statusCode;
    });
    req.end(); // make the request, returns just a boolean

    // return some result here?!
};

Si j'exécute mon code actuel en utilisant mocha en utilisant diverses options pour les requêtes HTTP, toutes les requêtes sont faites simultanément semble-t-il. Ils échouent tous, probablement parce que doRequest() ne retourne en fait rien:

describe('Requests', function() {
    var t = [ /* request options */ ];
    t.forEach(function(options) {
        it('should return 200: ' + options.path, () => {
            chai.assert.equal(doRequest(options), 200);
        });
    });
});
12
CoDEmanX

async/await travailler avec des promesses. Ils ne fonctionneront que si la fonction async que vous êtes awaiting renvoie une promesse.

Pour résoudre votre problème, vous pouvez soit utiliser une bibliothèque comme request-promise ou renvoyer une promesse de votre fonction doRequest.

Voici une solution utilisant ce dernier.

function doRequest(options) {
  return new Promise ((resolve, reject) => {
    let req = http.request(options);

    req.on('response', res => {
      resolve(res);
    });

    req.on('error', err => {
      reject(err);
    });
  }); 
}

describe('Requests', function() {
  var t = [ /* request options */ ];
  t.forEach(function(options) {
    it('should return 200: ' + options.path, async function () {
      try {
        let res = await doRequest(options);
        chai.assert.equal(res.statusCode, 200);
      } catch (err) {
        console.log('some error occurred...');
      }
    });
  });
});
24
mkhanoyan

vous devriez pouvoir simplement passer à votre fonction it . puis, après une requête asynchrone, vous ajouteriez la ligne done () après vos assertions. S'il y a une erreur, vous la transmettrez à la fonction done comme done (myError)

https://mochajs.org/#asynchronous-code pour plus d'informations

0
LostJon