Не очень легко понять обещания и доходность, особенно если вы не знаете, как они работают под капотом. Итак, начнем с основ. Первое, что нужно понять, это то, что Javascript является однопоточным, что означает, что он может выполнять только одно действие одновременно. Вы по-прежнему можете использовать несколько вещей одновременно, потому что в JavaScript есть то, что называется циклом обработки событий.
Цикл событий в основном выглядит примерно так:
while(queue.waitForTasks()) {
queue.performNextTask();
}
Цикл обработки событий проверяет наличие новых «задач» для запуска Javascript. Если есть задача. затем он выполняется до тех пор, пока не останется больше задач для выполнения. И он будет ждать своего нового задания. Эти задачи хранятся в чем-то, что называется очередью.
Обещания, Async / Await
Теперь мы понимаем, как Javascript обрабатывает различные задачи. Как это работает с обещаниями и async / await? promise
- это не что иное, как задача, или, в случае Javascript, то, что содержит задачу, которая будет добавлена в очередь и выполнена после выполнения всех задач перед ее выполнением. .then()
- это способ обеспечения обратного вызова для вашего обещания, которое выполняется после вызова обратного вызова.
Ключевое слово await [something]
сообщает Javascript: "Эй, поставь следующий [something]
в конец своей очереди и вернись ко мне, как только у [something]
будет результат.
Функция с ключевым словом async
в основном говорит Javascript: «Эта функция - обещание, но выполняй ее немедленно».
Поток асинхронной функции проще всего понять / продемонстрировать с помощью двух разных асинхронных функций A и B, например:
const A = async () => {
console.log(A: Start);
for (var i = 0; i < 3; i++) {
await (async () => console.log('A: ' + i));
}
console.log('A: Done');
}
const B = async () {
console.log(B: Start);
for (var i = 0; i < 3; i++) {
await (async () => console.log('B: ' + i));
await (async () => {/* A task without output */});
}
console.log('B: Done');
}
Когда вы вызываете ваши функции с await следующим образом:
console.log('Executing A');
await A();
console.log('Executing B');
await B();
это приведет к:
Executing A
A: Start
A: 0
A: 1
A: 2
A: Done
Executing B
B: Start
B: 0
B: 1
B: 2
B: Done
и работает:
console.log('Executing A');
A();
console.log('Executing B');
B();
приведет к:
Executing A
A: Start Note: still gets ran before Executing B
Executing B
B: Start
A: 0
B: 0
A: 1
A: 2 Note: A: 2 first because another task in B was put in the queue
A: Done
B: 1
B: 2
B: Done
Понимание этого может помочь лучше понять поток вашего приложения.
выход
Ключевое слово yield
похоже на await
в том смысле, что «внешняя сила» контролирует, когда он продолжает выполнение функции. В этом случае не завершение задачи обещания, а функция generator.next()