#javascript #async-await
Вопрос:
Описание
Я хочу условно вызвать базу SELECT
данных в несинхронной функции. Я завернул его в IIAEF?
такой вот
async function getScopedDataPolicies() {
const test = new Promise((res) => {
console.log('2')
res('test1')
})
return test;
}
function nonAsyncMethod() {
(async () => {
console.log('1')
const test = getScopedDataPolicies();
const policies = await test;
console.log('3')
})()
console.log('4')
}
nonAsyncMethod()
Мои ожидания таковы
1
2
3
4
Но я понимаю
1
2
4
3
Что бы не await
сработало в методе немедленного вызова??
Посмотрите на эти примеры; я что-то упускаю? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function
Комментарии:
1. ожидание ждет внутри IIFE … код за пределами IIFE не работает — кстати, заказ, который я получаю, является (ожидаемым) 2,3,1 — не уверен, как вы получаете 1,3,2 — вы, должно быть, неправильно его читаете
2. Я исправил
console.logs
это, чтобы лучше отразить то, что я имею в виду @JaromandaX3. да, теперь ваш фактический вывод отражает код в вопросе — причина та же, что и в первом комментарии … асинхронность/ожидание внутри IIFE не влияет на код после него, т. Е.
console.log('4')
не «ждет»await test
4. Я знаю … Вопрос в том, почему бы и нет? Почему этого ждут… на самом деле ничего не жду. Если я запускаю синхронный код, он работает…
5. это ДЕЙСТВИТЕЛЬНО ждет … но это ожидание находится внутри жизни, а не за ее пределами
Ответ №1:
Все await
, что нужно, — это приостановить выполнение текущей функции до завершения асинхронной задачи, после чего выполнение будет продолжено. Он не приостанавливает весь Javascript, такое поведение является синхронным программированием, и Javascript создан, чтобы избежать этого, потому что это создает действительно плохой пользовательский опыт, если Javascript должен останавливаться каждый раз, когда вы делаете запрос на отдых и т. Д.
Обновить
Некоторые возможные обходные пути:
- дождитесь IIFE или полностью выньте IIFE. IIFE-это асинхронная функция, поэтому она вернет обещание при вызове. Вы не ждете этого обещания, поэтому ваша функция внешней синхронизации продолжается, не дожидаясь ее завершения.
async function nonAsyncMethod() {
await (async () => {
console.log('1')
const test = getScopedDataPolicies();
const policies = await test;
console.log('3')
})()
console.log('4')
}
- Переезжай
console.log('4')
в свою ЖИЗНЬ. Я знаю, чтоconsole.log('4')
это может представлять собой целый журнал кода, но в некоторых случаях вам просто нужно переместить все это внутрь — разбить свою функцию на более мелкие функции, если потребуется.
Комментарии:
1. Я все еще не понимаю. Выполнение
getScopedDataPolicies
не завершено, и оно все еще находится в пределахIIFE
?2. Основываясь на том, что я пытаюсь сделать, у вас есть решение?
3. @Фил Я обновил свой ответ, чтобы дать вам некоторые решения.
Ответ №2:
ожидание внутри IIFE не влияет на внешнюю функцию
Для этого вы могли бы либо сделать это:
async function getScopedDataPolicies() {
const test = new Promise((res) => {
console.log('2')
res('test1')
})
return test;
}
async function nonAsyncMethod() {
await (async () => {
console.log('1')
const test = getScopedDataPolicies();
const policies = await test;
console.log('3')
})()
console.log('4')
}
nonAsyncMethod()
или это:
async function getScopedDataPolicies() {
const test = new Promise((res) => {
console.log('2')
res('test1')
})
return test;
}
function nonAsyncMethod() {
(async () => {
console.log('1')
const test = getScopedDataPolicies();
const policies = await test;
console.log('3')
})().then(() => {
console.log('4')
})
}
nonAsyncMethod()
Примечание: если вам нужно «подождать» nonAsyncMethod
— вы можете сделать только await nonAsyncMethod()
, или nonAsyncMethod.then(() => { continue here })