Асинхронизация / ожидание: нужно ли ожидать, когда асинхронные вложенные функции автоматически ожидаются на уровень выше? - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть пара вопросов относительно того, как асинхронный / ожидающий поток проходит через уровни.Пример кода:

class Auth
  async validateJwt() { // A
    const result = await fetch(...) // #1
    return await result.json(); // #1.5
  }

  async createJwtOrValidateExisting() { // B
    const token = await validateJwt(); // #2
    return token.data;
  }
}

const auth = new Auth();

// React.js top level component
const App = props => {

  useEffect(() => { // C
    const tokenData = auth.createJwtOrValidateExisting(); // #3    
  }
}

Нужно ли ждать на этапах 2 и 3?

Если это так, я думаю, что мне также нужно ключевое слово async в строке C.

Я знаю, что ожидание приостанавливает выполнение, что необходимо на этапах fetch () и .json ().В первом методе это интуитивно понятно.

Но затем, когда вы ожидаете на шаге 2, я считаю, что для этого также требуется ключевое слово async в функции более высокого уровня, что означает, что обещание должно быть возвращено из него.Это кажется неуместным, потому что шаг .json () уже был обработан / разрешен на шаге 1.5.

Если эта интерпретация неверна и мне требуется async / await на шагах B / # 2, это означает, что я должен такжеПревратите обратный вызов useEffect в асинхронную функцию.

Любое объяснение правильного использования этих ключевых слов выше очень поможет, спасибо.

1 Ответ

1 голос
/ 28 сентября 2019

Нужно ли ждать на этапах 2 и 3?

Для #2, да.validateJwt - это функция async.Если вы позвоните без await, вы получите обещание.Если вы вызываете его с await, вы получите разрешенное значение этого обещания.

Для #3, useEffect НЕ является асинхронной функцией, поэтому вы должны использовать then для обработки обещаниявозвращается createJwtOrValidateExisting.Кроме того, вы можете сделать useEffect асинхронной функцией и использовать await для createJwtOrValidateExisting.

Кроме того, в #1.5 await в return await result.json() не требуется.response.json() возвращает обещание, которое вы можете немедленно вернуть из асинхронной функции.См. https://eslint.org/docs/rules/no-return-await

Это должно быть:

class Auth
  async validateJwt() {
    const result = await fetch(...)
    return result.json()
  }

  async createJwtOrValidateExisting() {
    const token = await validateJwt()
    return token.data
  }
}

const auth = new Auth();

const App = props => {

  async useEffect(() => {
    const tokenData = await auth.createJwtOrValidateExisting()
  }
}

Практическое правило заключается в том, что асинхронная функция - это просто функция, которая возвращает обещание.Если вы хотите извлечь его значение без использования then, сделайте функцию асинхронной и используйте await для этого обещания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...