在我的程序中,我使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。
答案 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
并根据callback
和error
解析或拒绝请求的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://...')