async / await for Node.js https.get



我正试图用async/await 简化代码

但是在制作具有异步/等待结构的https.get时存在问题。

我知道如何使用第三方模块,但更喜欢本机node.jshttps模块。

以下代码不适用于我:

async function get_page() {
const https = require('https')
const url = 'https://example.com'
const util = require('util')
const https_get = util.promisify(https.get)
const data = await https_get(url)
do_awesome_things_with_data(data)
}

此代码运行良好:

function get_page() {
const https = require('https')
const url = 'https://example.com'
let data = ''
https.get(url, res => {
res.on('data', chunk => { data += chunk }) 
res.on('end', () => {
do_awesome_things_with_data(data)
})
}) 
}

https.get不会返回可承诺的内容,因为回调的签名与(err, value)不匹配,所以您不能等待它。

但是,您可以像这样将https.get调用封装在Promise中,然后在调用get_page时等待

const https = require('https')
async function get_page() {
const url = 'https://example.com'
return new Promise((resolve) => {
let data = ''
https.get(url, res => {
res.on('data', chunk => { data += chunk }) 
res.on('end', () => {
resolve(do_awesome_things_with_data(data));
})
}) 
})
}
// usage
(async () => await get_page())()

编辑

我已经更新了我的答案,其中包含了https.get无法承诺的注释,并将require('https')移到了函数调用之外。

不要promisify,而是滚动自己的函数,或者使用第三方库。Promisify无法包装https.get返回的内容。

// generic promise method for https
const requestPromise = ((urlOptions, data) => {
return new Promise((resolve, reject) => {
const req = https.request(urlOptions,
(res) => {
let body = '';
res.on('data', (chunk) => (body += chunk.toString()));
res.on('error', reject);
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode <= 299) {
resolve({statusCode: res.statusCode, headers: res.headers, body: body});
} else {
reject('Request failed. status: ' + res.statusCode + ', body: ' + body);
}
});
});
req.on('error', reject);
req.write(data, 'binary');
req.end();
});
});

然后这样称呼它:

async function get_page() {
const url = 'https://example.com'
const data = await requestPromise({url, method:'GET'})
do_awesome_things_with_data(data)
}

或者简单地使用axios之类的库来返回本机promise,并处理其他样板案例。

以下是我的操作方法:

async myFunc = function {
let url = 'http://your.data/file';
let promise = new Promise((resolve, reject) => {
var data = '';
https.get(url, res => {
res.on('data', chunk => { data += chunk }) 
res.on('end', () => {
resolve(data);
})
}) 
});
let result = await promise; // wait until the promise resolves
doStuffWithResult(result);
};

在我的例子中,我获取了一个.json文件,所以我实际上使用了resolve(JSON.parse(data))来返回干净的json对象。

最新更新