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

Ale*_*ich 27 rest asynchronous request node.js async-await

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

var info = await api.MyRequest(value);
Run Code Online (Sandbox Code Playgroud)

模块代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

执行立即返回,但是result,并因此info包含请求对象和请求体- info.bodykey=value&...,不需要响应体.

我做错了什么?怎么修?什么是正确的request用法async,或者它只适用于这里提到的promises:为什么await不适用于节点请求模块?下面的文章提到了:在Node.js中掌握Async Await.

jfr*_*d00 45

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

await处理返回promise的函数,而不是返回返回request对象的函数,并希望您使用回调或事件监听器来了解事情何时完成.

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

因此,安装request-promise模块然后更改:

var request = require("request");
Run Code Online (Sandbox Code Playgroud)

对此:

const request = require("request-promise");
Run Code Online (Sandbox Code Playgroud)

然后,你可以这样做:

var result = await request(options);
Run Code Online (Sandbox Code Playgroud)


小智 13

很确定你也可以做到以下几点.如果您需要的是默认情况下不返回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);
      }
    })
  })
}
Run Code Online (Sandbox Code Playgroud)

  • 如果没有async关键字也可以正常工作,那么async的目的是什么?请回答这些问题。 (2认同)

cbd*_*per 10

我只是设法让它与async/await一起工作。我把它包在函数内部promisifiedRequest返回一个promise运行该请求callback并解析或它基于废品errorresponse

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);
})();
Run Code Online (Sandbox Code Playgroud)


max*_*x_i 7

对于不需要 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://...')
Run Code Online (Sandbox Code Playgroud)


mat*_*fax 6

由于request-promise已被弃用,以下是不依赖于 NPMrequest包的其他选项。got已经提到过,但它取决于其他 11 个包。相比之下,axios只有 1 个依赖项(用于重定向)。其他一切都是在原生 NodeJS 包之上实现和构建的。

这是使用 的相同示例axios

const axios = require('axios')
Run Code Online (Sandbox Code Playgroud)
const response = await axios.get(url)
const result = response.data
Run Code Online (Sandbox Code Playgroud)

TypeScript 中的单行:

const {data} = await axios.get(url)
Run Code Online (Sandbox Code Playgroud)