Задача на асинхронность в js

Рейтинг: 0Ответов: 2Опубликовано: 09.03.2023

Все привет! Несколько дней промучился с решение задачи по промисам, но к элегантному решению не пришел... Использовать setTimeout с различными таймингами є кажется тупо, но и вариант с Promise не могу что-то адекватное придумать. Помогите решить задачу и объяснить мене ее. Буду благодарен за любую помощь)) Используя известные средства асинхронного выполнения (setTimeout и Promise) и не изменяя вертикальный порядок вызова функций 2, 1, 4, 3 в исходном коде, внесите изменения в код таким образом, чтобы после полного завершения выполнения программы в массиве completionFlags содержалась последовательность ['1' , '2', '3', '4'].

Стартовый код:

const completionFlags = [];

async function asyncActions() {
   // ========== Начало зоны редактирования ===============
   action('2');
   action('1');
   action('4');
   action('3');
   // ========== Конец зоны редактирования ===============
}

function action(pos) {
   completionFlags.push(pos);
}

Ответы

▲ 0Принят

Используя известные средства асинхронного выполнения (setTimeout и Promise) и не изменяя вертикальный порядок вызова функций 2, 1, 4, 3 в исходном коде, внесите изменения в код таким образом, чтобы после полного завершения выполнения программы в массиве completionFlags содержалась последовательность ['1' , '2', '3', '4'].

Предложу такой вариант...

const completionFlags = [];

// Вызываем асинхронную функцию
asyncActions()
  .then(_ => console.log(completionFlags))
  .catch(console.log)

async function asyncActions() {
  // ========== Начало зоны редактирования ===============

  // запускаем все промисы и ждем их завершения
  return await Promise.all([
    action('2'),
    action('1'),
    action('4'),
    action('3'),
  ])
  // ========== Конец зоны редактирования ===============
}

function action(pos) {
  // возвращаем промис, который закончится через (pos * 10) милисекунд
  return new Promise(res => {
    // запускаем таймер, который по истечении своего времени запустит, переденную ему, функцию
    setTimeout(_ => {
      completionFlags.push(pos);
      // вызываем удачное завершение промиса
      res()
    }, pos * 10)
  })
}

Еще один вариант "только в зоне"...

const completionFlags = [];

asyncActions()
  .then(_ => console.log(completionFlags))
  .catch(console.log)

async function asyncActions() {
  // ========== Начало зоны редактирования ===============

  // запускаем все промисы и ждем их завершения
  return await Promise.all([
    // делаем промисы, которые завершатся в нужной нам последовательности
    new Promise(res => setTimeout(_ => (action('2'), res()), 2 * 10)),
    new Promise(res => setTimeout(_ => (action('1'), res()), 1 * 10)),
    new Promise(res => setTimeout(_ => (action('4'), res()), 4 * 10)),
    new Promise(res => setTimeout(_ => (action('3'), res()), 3 * 10)),
  ])
  // ========== Конец зоны редактирования ===============
}

function action(pos) {
  completionFlags.push(pos);
}

▲ 0
const completionFlags = [];

async function asyncActions() {
   // ========== Начало зоны редактирования ===============
   Promise.resolve().then(()=>{
      action('2'); // добавляем в очередь микрозадач
   })
   action('1');
   setTimeout(()=>{
    action('4'); // добавляем в очередь макрозадач
   }, 0)
   Promise.resolve().then(()=>{
      action('3'); // добавляем в очередь микрозадач
   })
   // ========== Конец зоны редактирования ===============
}

function action(pos) {
   completionFlags.push(pos);
}

asyncActions()

setTimeout(()=>{
 console.log(completionFlags) // добавляем в очередь макрозадач чтобы в конце посмотреть после всех очередей массив
}, 0)