Это сработало, потому что await
не требует, чтобы его операнд был обещанием! Возвращает значение ожидаемого выражения, если это не обещание.
См. документацию для оператора ожидания
Важная часть:
[rv] = await expression;
expression
A Promise or any value to wait for.
rv
Returns the fulfilled value of the promise, or the value itself if it's not a Promise.
В вашем случае getUserDetails
не возвращал обещание, а скорее некоторые данные обычного пользователя, поэтому выражение await
просто возвращало эти детали, как будто оператора вообще не было.
Однако , даже если getUserDetails
является синхронным, перед ним с await
в вашей асинхронной функции передаст управление своему вызывающему, а «часть обратного вызова» после await
поднят позже. Вот пример сценария:
function f() {
console.log('In f');
}
async function g() {
console.log('Starting g');
await f();
console.log('Finishing g');
}
console.log('Starting the script')
g();
console.log('Finishing the script')
Обратите внимание на вывод сценария:
$ node asynctest.js
Starting the script
Starting g
In f
Finishing the script
Finishing g
Обратите внимание, как await
вызвал "g", который не смог возобновиться, пока не закончился основной блок! Так что await
сделал эффект. Если бы вы не поместили ожидание там, то вы бы увидели «Завершение g» перед «Завершение сценария». Попробуйте!
Кстати, причина этого эффекта в том, что даже если await
может быть задано выражение, которое не создает обещание, JS превратит операнд без обещания в обещание, немедленно разрешенное до этого значения. Таким образом, обещание все еще создается, и часть после await обрабатывается как обратный вызов, который не может быть выполнен, пока не завершится текущий поток выполнения.