Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper request with async/await in Node.JS

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.

like image 361
Aleksey Kontsevich Avatar asked Aug 20 '17 04:08

Aleksey Kontsevich


People also ask

How can we use async await in node JS?

Async functions return a Promise by default, so you can rewrite any callback based function to use Promises, then await their resolution. You can use the util. promisify function in Node. js to turn callback-based functions to return a Promise-based ones.

Is it good to use await in node JS?

Using async/await in Node. js syntax is preferable to the alternatives, which are stock promises or especially callbacks. It allows for much cleaner code which is easier to understand and maintain.

How do you get a response from async method in node JS?

const https = require('https') async function fetch(url) { return new Promise((resolve, reject) => { const request = https. get(url, { timeout: 1000 }, (res) => { if (res. statusCode < 200 || res. statusCode > 299) { return reject(new Error(`HTTP status code ${res.

Does node js support async await?

Node. js 7.6 has shipped with official support for async / await enabled by default and better performance on low-memory devices.


2 Answers

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

EDIT Jan, 2020 - request() module in maintenance mode

FYI, the request module and its derivatives like request-promise are now in maintenance mode and will not be actively developed to add new features. You can read more about the reasoning here. There is a list of alternatives in this table with some discussion of each one.

I have been using got() myself and it's built from the beginning to use promises, supports many of the same options as the request() module and is simple to program.

like image 96
jfriend00 Avatar answered Sep 30 '22 18:09

jfriend00


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);        }      })    })  }
like image 21
user3520261 Avatar answered Sep 30 '22 18:09

user3520261