Как заставить перебор массива проходить по порядку

Есть следующий код на JS:

const demo = ['auto', 'bus', 'bike'];

demo.map((item) => {
  console.log('Появился ' + item);
  setTimeout(() => {
    console.log('Задержка 2 секунды ' + item);
  }, 2000);
  console.log('Отработал ' + item);
});

Он отрабатывает следующим образом: введите сюда описание изображения

Как мне заставить каждый элемент проходить сначала 3 операции, а уже потом переходить к следующему элементу массива? Чтобы выполнялись все 3 операции auto, пото все 3 bus, потом все 3 bike. Чтобы не происходило вот этого перескока?


Ответы (1 шт):

Автор решения: Sergey K.

Всё выполняется правильно. Ты говоришь "выполни функцию через 2 секунды", но в течение этих 2х секунд остальной скрипт продолжает работать. Это асинхронность.
Чтобы сделать задержку и её дождаться нужно реализовать метод sleep и код должен работать в асинхронной функции.

function sleep (seconds) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(function() {}), seconds * 1000)
  })
}

Теперь в своём переборе делай задержку, а не параллельное выполнение по таймеру.

async function display() {
    const demo = ['auto', 'bus', 'bike'];
    
    for(var i=0; i<demo.length; i++) {
        var item = demo[i];
        console.log('Появился ' + item);
        await sleep(2);
        console.log('Задержка 2 секунды ' + item);
        console.log('Отработал ' + item);       
    }
}

Также из замечаний по коду - в данном случае не нужна функция map, а нужно циклом пробегаться, то есть forEach. Но так как у нас асинхронные функции, то придётся использовать обычный цикл, так как асинхронный коллбэк запустил бы параллельно вывод вновь.

Источник реализации функции задержки: https://stackoverflow.com/questions/33289726/combination-of-async-function-await-settimeout

→ Ссылка