在Node.JS中使用async / await的正确请求

时间:2017-08-20 04:33:10

标签: node.js rest asynchronous request async-await

在我的程序中,我使async从另一个API模块调用我的函数:

var info = await api.MyRequest(value);

模块代码:

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

执行立即返回,但result因此info包含请求对象和请求正文 - info.body,如key=value&...,而不是必需的响应正文。

我做错了什么?怎么修? request使用async的正确用法是什么,或者只适用于此处提到的承诺:Why await is not working for node request module?以下文章提到了:Mastering Async Await in Node.js

5 个答案:

答案 0 :(得分:32)

您需要使用request-promise模块,而不是request模块或http.request()

await适用于返回promise的函数,而不是返回返回request对象的函数,并期望您使用回调或事件侦听器来了解事情何时完成。

request-promise模块支持与request模块相同的功能,但其中的异步函数返回promises,因此您可以使用.then()await而不是request var request = require("request"); 模块期望的回调。

所以,安装request-promise module然后更改:

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

到此:

var result = await request(options);

然后,你可以这样做:

a

答案 1 :(得分:9)

非常确定您也可以执行以下操作。如果您需要的是默认情况下不返回Promise,您可以通过新的Promise方法提供它。上面的答案虽然不那么冗长。

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

答案 2 :(得分:4)

由于request-promise已被弃用,因此以下其他选项不依赖NPM request软件包。 got已经被提及,但是它依赖于其他11个软件包。相反,axios仅具有1个依赖项(用于重定向)。其他所有内容都在本机NodeJS包的基础上实现并构建。

以下是使用axios的相同示例:

const axios = require('axios')
const response = await axios.get(url)
const result = response.data

TypeScript中的单行代码:

const {data} = await axios.get(url)

答案 3 :(得分:0)

我刚刚设法使其与 async / await 一起使用。我将其包装在函数promisifiedRequest中,以返回运行请求promise并根据callbackerror解析或拒绝请求的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);
})();

答案 4 :(得分:0)

对于不需要 cookie、重定向和重试等高级功能的简单情况,您可以使用原生 http/https 模块发出请求:

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.statusCode}`))
      }

      const body = []
      res.on('data', (chunk) => body.push(chunk))
      res.on('end', () => {
        const resString = Buffer.concat(body).toString()
        resolve(resString)
      })
    })

    request.on('error', (err) => {
      reject(err)
    })
    request.on('timeout', () => {
      request.destroy()
      reject(new Error('timed out'))
    })
  })
}

const res = await fetch('https://...')