我有一个用JavaScript编写的小代码,可以获取html页面的内容,然后对它们进行处理(搜寻器)。 问题是 请求 导致异步执行。 我尝试使用Promises和async&await,但是仍然遇到异步执行相同的问题,原因是我想一次抓取多个页面以便移至下一个目标。 这是我在这里的类似代码:
pack a_cost b_cost
0 2 10.5 5.25
1 2 12.0 6.00
2 2 11.0 5.50
3 2 13.0 6.50
结果应为: F1开始 链接1完成 链接2完成 链接3完成 链接4完成 链接5完成 链接6完成 链接7完成 链接8完成 链接9完成 链接10完成 f3
而不是 F1开始 链接1完成 f3 链接2完成 链接3完成 链接4完成 链接5完成 链接6完成 链接7完成 链接8完成 链接9完成 链接10完成
答案 0 :(得分:1)
注意:我将使用node-fetch之类的同构提取包来创建可在多种环境中使用的代码。即使您不打算在浏览器中使用它,熟悉API也会对将来的使用非常有益。至少,这个主意使我能够编写一个可以在StackOverflow上实际运行的代码段。
不过,无论使用哪种软件包,都 Promise.all()
是您的答案。您只需等待所有诺言解决,然后执行您的逻辑即可:
// const fetch = require('node-fetch')
const fetchData = (...args) => fetch(...args).then(r => {
if (!r.ok) throw new Error('Error!')
return r.json()
})
const getAllPostsAsync = (postIds) => Promise.all(
postIds.map(postId => fetchData(`https://jsonplaceholder.typicode.com/posts/${postId}`))
)
;(async () => {
const posts = await getAllPostsAsync([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
// TODO: Your logic here, after waiting for all posts to load
console.log(posts)
})()
答案 1 :(得分:0)
鉴于您想并行执行多个异步操作,您实际上并不想await
,因为这会阻塞您的功能。
首先,我想说的是找到一个使用Promise的HTTP库更好。您使用的一个具有回调,但是我相信request
项目还具有一个request-promise
软件包,它更易于使用。
这是f1函数的固定版本,可以更正确地使用promise。请注意,这还没有并行化。
const request = require('request-promise');
async function f1(){
log('f1 start');
for(let i=1;i<11;i++){
const res = await request(rootlink+i);
if(res.statusCode==200){
log('link '+i +' done');
}
}
}
这里是此函数的另一个版本,只是现在已经完全并行化了。
async function f1(){
log('f1 start');
const promises = [];
for(let i=1;i<11;i++){
promises.push(
request(rootlink+i).then( (res) => {
if(res.statusCode==200){
log('link '+i +' done');
}
})
);
}
await Promise.all(promises);
}
如果将其拆分为多个功能,可以使它更加优雅:
async function f1(){
log('f1 start');
const promises = [];
for(let i=1;i<11;i++){
promises.push(checkLink(i));
}
await Promise.all(promises);
}
async function checkLink(i) {
const res = await request(rootlink+i);
if (res.statusCode==200){
log('link '+i +' done');
}
}
答案 2 :(得分:0)
我的问题的答案是使用来自的同步请求“ sync-request” https://www.npmjs.com/package/sync-request