Есть две асинхронные функции:
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();
Продвижение своими сайтами как стратегия роста и независимости