简体   繁体   English

Javascript:map 异步 function 在数组上,在每个元素上保持执行,直到它返回前一个元素

[英]Javascript: map asynchronous function over array, holding execution on each element until it returns on the previous one

I am trying to build a flashcard app, and I have two things: an array with data about each flashcard and an asynchronous function that takes in an element of the array and displays the flashcard to the user.我正在尝试构建一个抽认卡应用程序,我有两件事:一个包含每个抽认卡数据的数组和一个异步function,它接收数组的一个元素并向用户显示抽认卡。 As soon as the function is executed, the card is drawn on the screen.只要执行 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
}

I want to loop over the cards in order, but I want only one card to show at a time.我想按顺序循环卡片,但我希望一次只显示一张卡片。 The problem is if I do this:问题是如果我这样做:

// not actual code, do not debug

flashcards.forEach((item) => {
    showCard(item)
})

...since the function is asynchronous, the browser displays all the flashcards at once, and they get all cluttered and unusable on the screen. ...由于 function 是异步的,浏览器会同时显示所有的抽认卡,它们在屏幕上变得杂乱无章且无法使用。

How can I loop over the cards in such a way that each card is drawn only after the user is done interacting with the previous card (ie, when showCard returns)?我怎样才能循环卡片,使得每张卡片只有在用户完成与前一张卡片的交互后才被绘制(即当 showCard 返回时)?

I don't think you're looking for an async solution but instead a flag to wait for user interaction.我认为您不是在寻找异步解决方案,而是在寻找等待用户交互的标志。

Something like:就像是:

let currentCardIndex = 0;

while (currentCardIndex < flashcards.length) {

    showCard(flashcards[currentCardIndex]);
    currentCardIndex++;
}

There are different approaches here you could either:这里有不同的方法,您可以:

  1. Spawn a promise and wait for a return value from using thenable semantics.产生一个 promise 并等待使用 thenable 语义的返回值。
  2. Pass a callback too which call with the return value when the user is done with UI也传递一个回调,当用户完成 UI 时使用返回值调用
  3. Event emitter to emit that a card has been processed with a return value.事件发射器发出卡已被处理并返回值。

Promise Promise

Pseudocode for promise based solution基于 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
  })
}

Callback打回来

Pseudocode for callback based solution基于回调的解决方案的伪代码


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
}

Event emitter or Custom Events事件发射器或自定义事件

Pseudocode for event emitter or custom events based solution This assumes you either use a event emitter or custom events事件发射器或基于自定义事件的解决方案的伪代码假设您使用事件发射器自定义事件


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.

相关问题 暂停执行代码,直到异步函数返回所需值 - Pause execution of code until Asynchronous function returns the desired value JavaScript /异步函数调用是否有用于阻止直到函数返回的简写? - JavaScript/Asynchronous Function Calls Is there a Shorthand for blocking until function returns? 给定字符串数组,可以对每个字符串进行迭代并调用基于promise的函数,但是要等到上一次迭代完成后再继续吗? - Given array of strings, iterate over each and call promise based function, but wait to continue until the previous iteration finishes? 多个function的异步执行顺序各取最后一个 - Asynchronous execution order of multiple function each one depending on the last one Javascript映射函数是异步的吗? - Is Javascript Map Function Asynchronous? JavaScript 异步 Function 执行顺序 - JavaScript Asynchronous Function Execution Order 将数组作为输入的javascript函数,将每个数组元素加1,然后返回值增加的新数组不起作用 - javascript function that takes array as input, increases each array element by 1 and returns new array with increased values not working 将数组的每个值应用于一个元素,直到到达数组的末尾? - Apply each value of an array to one element until the end of the array is reached? 延迟执行脚本直到前一个脚本完成 - Delay execution of a script until the previous one finishes jQuery / Javascript-将功能的执行延迟到另一个功能完成为止 - jQuery/Javascript - Delay the execution of a function until another one is complete
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM