我试图更多地了解承诺和异步编程。我试图制作一个异步循环(是的,我知道有很多库可以实现这个,但他们不会教我如何工作)使用promises。
让我们说我想迭代一个数组,并将一个函数应用于一个元素"每个刻度"而我做其他一些事情。所以我做了这个" async for-loop-like"功能:
function asyncFor_(elements, worker, index) {
return new Promise((resolve, reject) => {
process.nextTick(()=>{
if (index < elements.length) {
try {
worker(elements[index])
resolve(asyncFor_(elements, worker, index+1))
} catch(e) {
reject()
}
} else {
resolve()
}
})
})
}
用这个测试它:
function logEnd() {
console.log('End')
}
function logErr(e) {
console.log(e) //Received
console.log('I dont like 3. GTFO.')
}
function logItem(item) {
if (item === 3) {
throw Error('3? GTFO.')
}
console.log(item)
}
console.log('Begin')
asyncFor_([1,2,3,4,5], logItem, 0)
.then(logEnd)
.catch(logErr)
asyncFor_([6,7,8,9], logItem, 0)
.then(logEnd)
.catch(logErr)
console.log('Displayed after begin and before the rest')
输出结果为:
Begin
1
6
2
7
8
I don't like 3. GTFO
9
End (End from the second asyncFor_ call)
我认为这很好用。但与此同时,我有疑虑。也许我误解了结果。我错过了什么?这是&#34;异步&#34;幻觉还是真的异步?
答案 0 :(得分:1)
是的,它很好,是的,它实际上是异步的(也可以通过两个并发循环的输出日志证明)。
然而,它看起来有点像Promise
constructor antipattern,并且通过避免它可以大大简化您的代码:
function nextTick() {
return new Promise(resolve => {
process.nextTick(resolve);
});
}
function asyncFor_(elements, worker, index) {
return nextTick().then(() => {
if (index < elements.length) {
worker(elements[index]);
return asyncFor_(elements, worker, index+1);
}
});
}
将代码放入then
回调中,您可以免费获得try-catch。始终在尽可能低的水平上进行宣传! : - )