Когда вы вызываете этот terminate()
, который является следующим:
function terminate() {
setTimeout(() => console.log("Edning"), 1)
}
setTimeout()
подталкивает его обратный вызов к будущему циклу события l oop и ВСЕГО остального в текущем цикле событие l oop запускается перед ним. Только когда текущая цепочка кода завершится и управление вернется обратно к событию l oop, setTimeout()
получит шанс запустить свой обратный вызов.
Итак, вот последовательность того, что происходит в вашем код:
call()
выполняется. myprom()
выполняется. Это немедленно выполняет свое обещание, поэтому он планирует запуск своих обработчиков .then()
, как только управление вернется к событию l oop. .then()
и .catch()
run. Все, что они делают в этот момент, это регистрируют некоторые обратные вызовы, которые будут вызваны позже, когда обещание будет готово для их выполнения. - Ваша функция asyn c возвращается, и управление возвращается к событию l oop.
- Уже обработанное обещание является первым в строке в событии l oop, поэтому оно получает управление и выполняет свой
.then()
обработчик. myfunc(1)
запускается и выводит Starting in 1
console.log(result)
запускается и выводит I Promise to end without showing next line
terminate()
запускается, и это устанавливает таймер на 1 мс с этого момента. Эта функция возвращается, и таймер запускается по расписанию для будущего тика события l oop, когда прошло 1 мс. Вызывается dummy(1)
, и выводится I am not supposed to print anything
. terminate()
вызывается снова, и это снова планирует запуск другого таймера через 1 мс в будущем тике события l oop. await
обрабатывает обещание и разрешает обещание, которое async
функция call()
возвращает. await
не делает здесь ничего полезного, и нечего ожидать от обещания, что call()
тоже вернет. - Управление возвращается обратно событию l oop.
- Первый таймер, который вы установили при первом вызове
terminate()
, запускается, и он выводит. Это возвращает управление событию l oop. - Второй таймер, который вы установили при втором вызове
terminate()
, запускается и запускается. Это возвращает управление событию l oop, и все, что связано с этим кодом, выполняется.
В общем. как внезапно остановить выполнение js внутри объекта .then?
Если вы спрашиваете, как пропустить другие функции, которые вызываете все подряд, то вы обычно используете условные выражения для перехода из return
в начале обратного вызова .then()
. Например, вы можете сделать это:
async function call() {
await myprom("to end without showing next line")
.then(result => {
myfunc(1) // Call # 1
console.log(result) // Call # 2
if (result === "I Promise to end without showing next line") {
// skip the rest of the code in this callback
return;
}
terminate() // Call # 3
dummy(1) // Call # 4
terminate() // Call # 5
})
.catch(err => {
console.log(err)
})
}
call()
Поскольку вы находитесь в обработчике .then()
, вы также можете сделать throw someError
, и это внезапно остановит обработчик .then()
, как и бросить любой исключение прерывает выполнение текущей функции. Поскольку это находится в обработчике .then()
, это исключение будет немедленно перехвачено, а затем выполнится обработчик .catch()
и передаст ему созданное вами исключение. Обычно это не используется для обычного пути выполнения, потому что это чаще указывает на некоторую ошибку. Обычный путь выполнения, скорее всего, отловит условие локально и использует ветвление или if/else
logi c или что-то в этом роде, чтобы решить, какой код в функции будет выполняться следующим.
Обратите внимание, если вы ' вы уже запустили некоторые таймеры, а затем, чтобы они не срабатывали, вам нужно сохранить timerID
, который возвращается setTimeout()
, и использовать clearTimeout()
на этом timerID
, чтобы отменить таймер.
Если вы действительно хотите резкую остановку, чтобы остановить весь процесс, тогда в node.js вы также можете позвонить process.exit()
.
Непонятно, почему вы подумали, что вывод из dummy(1)
и второй вызов terminate()
не будет отображаться на выходе? Вы позвонили по номеру dummy(1)
. Ничто в функции terminate()
не заставляет Javascript пропускать остальную часть кода в обработчике .then()
. Итак, он продолжает и выполняет как dummy(1)
, так и второй terminate()
, и вы видите результат обоих.