Javascript 异步:每个函数永远不会完成
我正在尝试使用来处理二维数组,并处理每个展平的项。像这样:Javascript 异步:每个函数永远不会完成,javascript,typescript,asynchronous,async.js,Javascript,Typescript,Asynchronous,Async.js,我正在尝试使用来处理二维数组,并处理每个展平的项。像这样: 从'async'导入{each}; let结果:任意[]=[]; 等待每个(聊天,异步(聊天)=> 等待每个参与者(chat.participants,异步(participant)=>{ console.log(“暂停前”); //与参与者做点什么 结果:推送(fn(参与者)); 等待这个。超时(2500); console.log('After pause'); }) ); console.log('Finished'); 返回结果
从'async'导入{each};
let结果:任意[]=[];
等待每个(聊天,异步(聊天)=>
等待每个参与者(chat.participants,异步(participant)=>{
console.log(“暂停前”);
//与参与者做点什么
结果:推送(fn(参与者));
等待这个。超时(2500);
console.log('After pause');
})
);
console.log('Finished');
返回结果;
在哪里
let chats=[
{
参与者:['1','2']
},
{
参与者:['3','4']
}
]
超时(毫秒){
返回新承诺(resolve=>setTimeout(resolve,ms));
}
但是,console.log('Finished')
从不执行。在这段代码中,我尝试了大量的async
和await
变体,但无法使其正常工作。我有一个使用纯async/await的工作版本,但是我想使用async库
我做错了什么
请注意,我确实可以使用async/await而不使用async库,如下所示:
等待承诺。全部(chats.map(
异步(聊天)=>
等待承诺。所有(聊天室)参与者
.map(异步(参与者)=>{
console.log(“暂停前”);
//与参与者做点什么
结果:推送(fn(参与者));
等待这个。超时(2500);
console.log('After pause');
})
)
));
返回结果;
但是我想使用异步库,因为我希望使用该库中的其他函数。试试这个
let chats = [
{
participants: ['1', '2']
},
{
participants: ['3', '4']
}
]
chats.forEach(chat =>
chat.participants.forEach(async (participant) => {
console.log('Before pause');
// do something with participant
await timeout(2500);
console.log('After pause');
console.log(participant)
}));
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
console.log('Finished');
问题:-
- 等待仅在异步函数中有效
- 不要使用this.timeout,而是与某些上下文一起使用,或者直接在您的案例中使用。在js&
函数(项,回调){}
,每次迭代完成时都需要调用回调。注意这与each()
的可选第三个参数不同
解决方案是每次迭代调用回调,如下所示:
wait each(聊天,异步(聊天,done1/*1️⃣*/) => {
等待每个参与者(chat.participants,异步)(参与者,done2/*2️⃣*/) => {
//...
done2();/*3️⃣*/
});
done1();/*4️⃣*/
});
控制台日志(“完成”);
OP正在寻找一种显式使用async
库的解决方案。forEach
语句不是并行的。也看到了顶级等待。但他用typescript标记了它,typescript 3.8有顶级等待(在模块中,这是一个)是的,正如@Titulum所说,我想使用异步库,这样函数就可以并行运行。timeout()
正确地替代了我正在进行的异步API调用,在js中没有什么比并行更好的了(除非运行多个进程/线程),您只是将工作委派给下一个事件循环迭代。委派for loop不好,因为它是一个阻塞语句。在这种情况下,timeout是应该委派的语句。除此之外,使用PROMITE的全部目的是避免回调。无论如何,如果您想将循环执行委派给下一个迭代,请设置IMERMENT或process、 可以使用nextTick(小心明智地使用nextTick)。遗憾的是,这不起作用。演示中的console.log('Finished')
在异步函数内部,但它在需要的外部不起作用-我需要同步返回此函数的结果。