Задача на асинхронность в js
Все привет! Несколько дней промучился с решение задачи по промисам, но к элегантному решению не пришел... Использовать 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);
}
Ответы (2 шт):
Используя известные средства асинхронного выполнения (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);
}
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)