Ожидание / Асинхронность с условным оператором и IIAEF

#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 это, чтобы лучше отразить то, что я имею в виду @JaromandaX

3. да, теперь ваш фактический вывод отражает код в вопросе — причина та же, что и в первом комментарии … асинхронность/ожидание внутри IIFE не влияет на код после него, т. Е. console.log('4') не «ждет» await test

4. Я знаю … Вопрос в том, почему бы и нет? Почему этого ждут… на самом деле ничего не жду. Если я запускаю синхронный код, он работает…

5. это ДЕЙСТВИТЕЛЬНО ждет … но это ожидание находится внутри жизни, а не за ее пределами

Ответ №1:

Все await , что нужно, — это приостановить выполнение текущей функции до завершения асинхронной задачи, после чего выполнение будет продолжено. Он не приостанавливает весь Javascript, такое поведение является синхронным программированием, и Javascript создан, чтобы избежать этого, потому что это создает действительно плохой пользовательский опыт, если Javascript должен останавливаться каждый раз, когда вы делаете запрос на отдых и т. Д.

Обновить

Некоторые возможные обходные пути:

  1. дождитесь IIFE или полностью выньте IIFE. IIFE-это асинхронная функция, поэтому она вернет обещание при вызове. Вы не ждете этого обещания, поэтому ваша функция внешней синхронизации продолжается, не дожидаясь ее завершения.
 async function nonAsyncMethod() {
  await (async () => {
    console.log('1')
    const test = getScopedDataPolicies();
    const policies = await test;
    console.log('3')
  })()

  console.log('4')
}
 
  1. Переезжай 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 })