Во время выполнения урока по React ToolKit createAsyncThunk() мне дали инструкции составить асинхронную функцию обратного вызова, которую она принимает в качестве второго аргумента. Это приближение кода:

async () => {
  const response = await fetchUsers();
  return await response.json();
}

Роль этой функции обратного вызова заключается в предоставлении свойства полезной нагрузки действия для отправки в хранилище Redux для изменения состояния. В этом случае я извлекал список пользователей, чтобы передать их в качестве полезной нагрузки. fetchUsers() извлекает данные из API; затем данные преобразуются в объект JavaScript с помощью json() перед возвратом примечания.

После написания этой функции IDE, которую я использовал, выдала эту ошибку: «Совместное использование return и await неэффективно и следует избегать. Вместо этого вам следует разделить свои утверждения await и return».

Я переписал функцию в соответствии с инструкциями, возвращая переменную вместо оператора await:

async () => {
  const response = await fetchUsers();
  const users = await response.json();
  return users;
}

Это удовлетворило тестовую среду, но мне было любопытно: почему возвращаемый оператор await заметно отличался по эффективности от возвращаемого значения переменной, присвоенной возвращаемому значению того же самого оператора await?

Чтобы перейти к делу: заметной разницы нет. Источником этой директивы, вероятно, является документация для ESLint, в которой есть правило без ожидания возврата; он выдаст ошибку, если await встречается в операторе return в вашем коде. Вы можете обойти это правило, как я сделал выше, разделив return и await на отдельные операторы. Однако это не существенно повысит эффективность.

На самом деле, если эффективность действительно важна при работе с асинхронной функцией, в приведенных выше примерах следует вообще отказаться от второго оператора await:

async () => {
  const response = await fetchUsers();
  return response.json();
}

Учитывая, что асинхронные функции всегда возвращают обещание, второй оператор await по существу является избыточным. Если значение, возвращаемое вторым оператором await, все равно будет заключено в промис, добавляется шаг путем await-обработки возвращаемого значения response.json() вместо простого возврата самого выражения (поскольку .json() является асинхронной функцией, она возвращает промис) . Это очень полезная демонстрация дополнительной работы по возврату оператора await.

По сути, это то, что правило ESLint пытается воспрепятствовать. Но здесь важно отметить, что все вышеупомянутые варианты одной и той же асинхронной функции будут работать правильно; все они вернут обещание, которое разрешается в список объектов пользователей. И, если производительность не является первоочередной задачей (в этом случае она, вероятно, не должна быть), есть преимущество в возврате инструкции await. Таким образом, он добавляется в трассировку стека, потенциально избавляя от головной боли, если это часть большого проекта и требуется отладка. По сути, это хорошая защитная мера с, вероятно, очень незначительным компромиссом в эффективности.

Подводя итог: для большинства практических целей, вероятно, предпочтительнее игнорировать ESLint и возвращать этот оператор await.

использованная литература