javascript:异步函数问题(异步等待循环)

时间:2020-01-01 21:48:04

标签: javascript loops asynchronous promise async-await

我在javascript中的异步功能有问题

我的功能如下:

async function animate(animations) {
  const promises = animations.map(async(element, index) => {
    const arrayBars = document.getElementsByClassName(classes.arrayElement);
    if (element.operation === 'change-color') {
      const [barOneIndex, barTwoIndex] = element.positions;
      const barOneStyle = arrayBars[barOneIndex].style;
      const barTwoStyle = arrayBars[barTwoIndex].style;
      setTimeout(() => {
        barOneStyle.backgroundColor = SECONDARY_COLOR;
        barTwoStyle.backgroundColor = SECONDARY_COLOR;
      }, index * speed);
    }
    if (element.operation === 'revert-color') {
      const [barOneIndex, barTwoIndex] = element.positions;
      const barOneStyle = arrayBars[barOneIndex].style;
      const barTwoStyle = arrayBars[barTwoIndex].style;
      setTimeout(() => {
        barOneStyle.backgroundColor = PRIMARY_COLOR;
        barTwoStyle.backgroundColor = PRIMARY_COLOR;
      }, index * speed);
    }
    if (element.operation === 'swap') {
      setTimeout(() => {
        const [barOneIndex, newHeight] = element.positions;
        const barOneStyle = arrayBars[barOneIndex].style;
        barOneStyle.height = `${newHeight / 1.4}px`;
      }, index * speed);
    }
  });
  await Promise.all(promises);
  console.log('finished');
}

它基本上是一种动画排序算法,这是项目的链接,可帮助您更轻松地理解:https://divino.dev/Sorting-algorithms-visualizer/

问题是,我需要知道动画何时结束,但是我尝试的所有操作都没有等待动画完成。

2 个答案:

答案 0 :(得分:0)

我看到您的.map()函数没有返回任何承诺。您可以使用

修复此问题
const promises = animations.map((element, index) => new Promise((resolve, reject) => { 
   const arrayBars = ...
   ...
   resolve();
}))
await Promise.all(promises);
console.log('finished');

答案 1 :(得分:0)

要使promises是一个Promises数组,.map()回调需要返回Promise。

为此,您需要承诺setTimeout,为此,标准做法是编写一个小的Promise-returning delay()函数。

async function animate(animations) {
    function delay(ms) {
        return new Promise((resolve) => {
            setTimeout(resolve, ms);
        });
    }
    const promises = animations.map(async(element, index) => {
        const arrayBars = document.getElementsByClassName(classes.arrayElement);
        return delay(index * speed).then(() => {
            if (element.operation === 'change-color') {
                const [barOneIndex, barTwoIndex] = element.positions;
                arrayBars[barOneIndex].style.backgroundColor = SECONDARY_COLOR;
                arrayBars[barTwoIndex].style.backgroundColor = SECONDARY_COLOR;
            }
            if (element.operation === 'revert-color') {
                const [barOneIndex, barTwoIndex] = element.positions;
                arrayBars[barOneIndex].style.backgroundColor = PRIMARY_COLOR;
                arrayBars[barTwoIndex].style.backgroundColor = PRIMARY_COLOR;
            }
            if (element.operation === 'swap') {
                const [barOneIndex, newHeight] = element.positions;
                arrayBars[barOneIndex].style.height = `${newHeight / 1.4}px`;
            }
        });
    });
    await Promise.all(promises);
    console.log('finished');
}

请注意,由于三种情况下的延迟都是相同的,因此将delay(index * speed).then(...)作为外部结构,将决策if(){...} if(){...} if(){...}作为内部结构(或等效或switch/case结构)。