Proper request with async/await in Node.JS

霸气de小男生 提交于 2019-12-17 16:32:11

问题


In my program I make async call for my function from another API module:

var info = await api.MyRequest(value);

Module code:

var request = require("request")

module.exports.MyRequest = async function MyRequest(value) {
    var options = {
        uri: "http://some_url",
        method: "GET",
        qs: {  // Query string like ?key=value&...
            key : value
        },
        json: true
    }

    try {
        var result = await request(options);
        return result;
    } catch (err) {
        console.error(err);
    }
}

Execution returns immediately, however result and therefore info contains request object and request body - info.body like key=value&..., not required response body.

What I'm doing wrong? How to fix? What is proper request usage with async, or it only works correctly with promises like mentioned here: Why await is not working for node request module? Following article mentioned it is possible: Mastering Async Await in Node.js.


回答1:


You need to use the request-promise module, not the request module or http.request().

await works on functions that return a promise, not on functions that return the request object and expect you to use callbacks or event listeners to know when things are done.

The request-promise module supports the same features as the request module, but asynchronous functions in it return promises so you can use either .then() or await with them rather than the callbacks that the request module expects.

So, install the request-promise module and then change this:

var request = require("request");

to this:

const request = require("request-promise");

Then, you can do:

var result = await request(options);



回答2:


Pretty sure you can also do the following. If what you need does not return Promise by default you can provide it via new Promise method. Above answer is less verbose though.

async function getBody(url) {
  const options = {
    url: url,
    method: 'GET',
  };

  // Return new promise
  return new Promise(function(resolve, reject) {
    // Do async job
    request.get(options, function(err, resp, body) {
      if (err) {
        reject(err);
      } else {
        resolve(body);
      }
    })
  })
}



回答3:


I just managed to get it to work with async/await. I wrapped it inside a function promisifiedRequest to return a promise that runs the request callback and resolves or rejects it based on error and response.

const request = require('request');

const promisifiedRequest = function(options) {
  return new Promise((resolve,reject) => {
    request(options, (error, response, body) => {
      if (response) {
        return resolve(response);
      }
      if (error) {
        return reject(error);
      }
    });
  });
};

(async function() {
  const options = {
    url: 'https://www.google.com',
    method: 'GET',
    gzip: true,
    headers: {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36'
    }
  };

  let response = await promisifiedRequest(options);

  console.log(response.headers);
  console.log(response.body);
})();


来源:https://stackoverflow.com/questions/45778474/proper-request-with-async-await-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!