Есть две асинхронные функции:
async function a() {
for (var i = 0; i <= 10000; i++) {
console.log(`${i} (a)`);
}
}
async function b() {
for (var i = 0; i <= 10000; i++) {
console.log(`${i} (b)`);
}
}
и функция c
, вызывающая функции a
и b
:
function c() {
a();
b();
}
Если вызвать функцию c
, то выводом будет последовательное выполнение функции a
(все 10000 итераций), затем функции b
.
Если функции a
и b
изменить таким образом:
async function a() {
return new Promise((resolve) => {
for (var i = 0; i <= 10000; i++) {
console.log(`${i} (a)`);
}
resolve();
});
}
async function b() {
return new Promise((resolve) => {
for (var i = 0; i <= 10000; i++) {
console.log(`${i} (b)`);
}
resolve();
});
}
То результат останется прежним. Мне нужно сделать так, чтобы их выводы смешались, чтобы выводилось условно
А не
Как сделать это правильно и можно ли вообще?
JavaScript однопоточный, и асинхронные функции сами решают, когда приостановить работу и передать управление другим функциям, с помощью await
. Циклы в функциях никто никогда не прервёт, пока сама функция не решит, что цикл можно прервать.
async function a() {
for (var i = 0; i <= 10; i++) {
console.log(`${i} (a)`);
// Возвращаем выполнение браузеру, чтобы он повыполнял другие задачи
// (например, цикл в b)
await null;
}
}
async function b() {
for (var i = 0; i <= 10; i++) {
console.log(`${i} (b)`);
// Возвращаем выполнение браузеру, чтобы он повыполнял другие задачи
// (например, цикл в a)
await null;
}
}
function c() {
a().then(() => console.log('a отработал'));
b().then(() => console.log('b отработал'));
}
c();
Вариант, когда цикл передаёт управление другим задачам не каждый раз, а через несколько итераций:
async function a() {
for (var i = 0; i <= 10; i++) {
console.log(`${i} (a)`);
if (i % 3 === 2) await null;
}
}
async function b() {
for (var i = 0; i <= 10; i++) {
console.log(`${i} (b)`);
if (i % 3 === 2) await null;
}
}
function c() {
a().then(() => console.log('a отработал'));
b().then(() => console.log('b отработал'));
}
c();
Или пример с асинхронной обёрткой над setTimeout
:
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function a() {
for (var i = 0; i <= 10; i++) {
console.log(`${i} (a)`);
// Спим полсекунды, чтобы поработал кто-то ещё
await sleep(500);
}
}
async function b() {
for (var i = 0; i <= 10; i++) {
console.log(`${i} (b)`);
// Спим четверть секунды для разнообразия
await sleep(250);
}
}
function c() {
a().then(() => console.log('a отработал'));
b().then(() => console.log('b отработал'));
}
c();
Чтобы вывод мог перемешиваться, каждая из итерация тоже должна быть асинхронной.
Например используя setTimeout
и await
async function a() {
for (var i = 0; i <= 10; i++) {
await new Promise(r => setTimeout(() => r(console.log(`${i} (a)`))));
}
}
async function b() {
for (var i = 0; i <= 10; i++) {
await new Promise(r => setTimeout(() => r(console.log(`${i} (b)`))));
}
}
function c() {
a();
b();
}
c();
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Команда new WebSocket("ws://46229
В Safari не работает, но работает в Google Chrome, OperaНе могу понять в чем проблема