我在 nodejs 中使用请求模块从某些网站提取数据。
let asyncFunction = () => {
let listWeb = ['https://www.npmjs.com/package/request', 'https://www.npmjs.com/package/cheerio']
let promiseArray = []
listWeb.forEach(async element => {
await requestpromise({
url: element,
method: "GET",
proxy: "http://sacombank%5Cdatnq29692%3ASatureday%40123@192.168.95.100:3128",
strictSSL: false,
//resolveWithFullResponse: true
})
.then(res => {
let $ = cheerio.load(res);
let name = $('#top > div.w-100.ph0-l.ph3.ph4-m > h2 > span');
name.each((ind, ele) => {
console.log(ele.attribs.title);
promiseArray.push(ele.attribs.title);
});
})
.catch(err => {
console.log(err);
});
})
console.log(promiseArray);
}
asyncFunction()
我想从终端看到的结果是:
['request','cheerio']
但响应也像:
[]
request
cheerio
你们能帮忙修复它并解释一下 async 和 await 函数以及我的代码有什么问题吗? 非常感谢!!!
最佳答案
欢迎来到 Node.js 中 Javascript 和 http 请求的异步世界。除非在非常特定的情况下,Javascript 中的异步操作是非阻塞的,并且不会停止您的代码流。当异步操作在后台运行时,代码会继续运行。在这个特定的函数中,这意味着您的 .forEach()
循环不会等待 await
完成(因为 .forEach()
不是 promise 意识)。
而且,您的函数会在任何一个 await requestpromise()
操作完成之前返回(这就是您首先在日志中获取 []
的原因)。因此,您不能在那里查看结果,因为尚未计算结果。
您可以通过进行一些更改来解决问题。由于您的请求是独立的,因此您可以并行运行它们并使用 Promise.all()
告诉您它们何时完成并按顺序收集结果。这也应该比尝试一次执行一个操作运行得快一点。
let asyncFunction = () => {
let listWeb = ['https://www.npmjs.com/package/request', 'https://www.npmjs.com/package/cheerio']
return Promise.all(listWeb.map(element => {
return requestpromise({
url: element,
method: "GET",
proxy: "http://sacombank%5Cdatnq29692%3ASatureday%40123@192.168.95.100:3128",
strictSSL: false,
//resolveWithFullResponse: true
}).then(res => {
let $ = cheerio.load(res);
let name = $('#top > div.w-100.ph0-l.ph3.ph4-m > h2 > span');
// get an array of title values and make that the resolved value
// of this promise
return name.map((ind, ele) => {
return ele.attribs.title;
}).get();
})
})).then(results => {
console.log(results.flat());
}).catch(err => {
console.log(err);
})
}
asyncFunction();
如果您想对这两个操作进行排序,则需要将 .forEach()
替换为常规的 for
语句。 for
用于暂停 await
。 .forEach()
并不是为了在其回调中暂停 await
而构建的。这可能看起来像这样:
let asyncFunction = async () => {
let listWeb = ['https://www.npmjs.com/package/request', 'https://www.npmjs.com/package/cheerio']
let results = [];
try {
for (let element of listWeb) {
let res = await requestpromise({
url: element,
method: "GET",
proxy: "http://sacombank%5Cdatnq29692%3ASatureday%40123@192.168.95.100:3128",
strictSSL: false,
//resolveWithFullResponse: true
});
let $ = cheerio.load(res);
let name = $('#top > div.w-100.ph0-l.ph3.ph4-m > h2 > span');
name.each((ind, ele) => {
results.push(ele.attribs.title);
});
}
console.log(results);
} catch(e) {
console.log(e);
}
}
asyncFunction()
关于javascript - Node JS - 从异步函数获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59573118/