[英]Javascript: map asynchronous function over array, holding execution on each element until it returns on the previous one
我正在尝试构建一个抽认卡应用程序,我有两件事:一个包含每个抽认卡数据的数组和一个异步function,它接收数组的一个元素并向用户显示抽认卡。 只要执行 function,就会在屏幕上绘制卡片。
// not actual code, do not debug
const flashcards = [card1, card2, card3] // except way more cards
function showCard(card){
// immediately draws the card
// waits for user interaction
// returns a value when the user is done with the card
}
我想按顺序循环卡片,但我希望一次只显示一张卡片。 问题是如果我这样做:
// not actual code, do not debug
flashcards.forEach((item) => {
showCard(item)
})
...由于 function 是异步的,浏览器会同时显示所有的抽认卡,它们在屏幕上变得杂乱无章且无法使用。
我怎样才能循环卡片,使得每张卡片只有在用户完成与前一张卡片的交互后才被绘制(即当 showCard 返回时)?
我认为您不是在寻找异步解决方案,而是在寻找等待用户交互的标志。
就像是:
let currentCardIndex = 0;
while (currentCardIndex < flashcards.length) {
showCard(flashcards[currentCardIndex]);
currentCardIndex++;
}
这里有不同的方法,您可以:
基于 promise 的解决方案的伪代码
let aCardIsVisible = false
function onShowFlashcardHandler (cardId) {
// a card is already visible return
if (aCardIsVisible) {
return
}
const card = flashcards.find(card => card.id === cardId)
if (card) {
// toggle on flag
aCardIsVisible = true
showCard(card)
.then(value => {
// do something with return value
// toggle off flag
aCardIsVisible = false
})
}
}
function showCard (card) {
return new Promise((resolve) => {
// draw card
// on some UI input or timeout loop for checking UI changes
loop :=
if UI done then
value <- UI input value
resolve(value)
end
endloop
})
}
基于回调的解决方案的伪代码
let aCardIsVisible = false
function onShowFlashcardHandler (cardId) {
// a card is already visible return
if (aCardIsVisible) {
return
}
const card = flashcards.find(card => card.id === cardId)
if (card) {
// toggle on flag
aCardIsVisible = true
showCard(card, (value) => {
// do something with return value
// toggle off flag
aCardIsVisible = false
})
}
}
function showCard (card, callback) {
// draw card
// on some UI input or timeout loop for checking UI changes
loop :=
if UI done then
value <- UI input value
callback(value)
end
endloop
}
事件发射器或基于自定义事件的解决方案的伪代码假设您使用事件发射器或自定义事件
let aCardIsVisible = false
function onShowFlashcardHandler (cardId) {
// a card is already visible return
if (aCardIsVisible) {
return
}
const card = flashcards.find(card => card.id === cardId)
if (card) {
// toggle on flag
aCardIsVisible = true
showCard(card)
}
}
function onCardDone (value) {
// do something with return value
// toggle off flag
aCardIsVisible = false
}
function showCard (card) {
// draw card
// on some UI input or timeout loop for checking UI changes
loop :=
if UI done then
value <- UI input value
emitter.emit('cardDone', value) // event emitter
element.dispatchEvent('cardDone', value) // custom event
end
endloop
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.