Нужно ли объявлять функцию как асинхронную, чтобы вернуть обещание?

Я использую вспомогательную функцию (fetchGet), возвращающую асинхронную функцию, которая возвращает обещание (fetchWrapper). Нужно ли объявлять эту вспомогательную функцию как асинхронную по отношению к самой себе, возвращающей обещание?

В моем случае здесь используется выборка, которую нужно ожидать в моей первой функции fetchWrapper (здесь упрощено для удобочитаемости):


// returns a promise
async function fetchWrapper(url, method) {
  const response = await fetch(url, {method: method});
  if (!response.ok) {
    throw new Error("HTTP error " + response.status);
  }
  return response;
}

async function fetchGet(url) {
  return fetchWrapper(url, 'GET');
}

async function getSpecificData() {
  return fetchGet('/a/specific/url');
}

Нужно ли мне объявлять функцию fetchGet как асинхронную функцию, как указано выше, чтобы она возвращала обещание?

Или я могу просто объявить это как обычную синхронную функцию, как показано ниже? (это действительно тот же случай для функции getSpecificData)

function fetchGet(url) {
  return fetchWrapper(url, 'GET');
}
async функции автоматически возвращают промис, если в вашем коде ничего не возвращается (независимо от того, что возвращает ваш код, результат будет заключен в промис).
briosheje 22.05.2019 11:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
638
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Does this helper function need to be declared as asynchronous to itself return a promise?

Нет.

async функции всегда возвращают обещания, даже если оператор return возвращает что-то, что не является обещанием. async функции позволяют вам управлять другими промисами внутри них, используя await

Вы можете явно вернуть обещание из любой функции.

Ответ принят как подходящий

Does a function need to be declared as asynchronous to return a promise?

Нет, совсем нет. На самом деле, обещания существовали задолго до того, как async начала функционировать.

Ваша обертка может быть просто:

function fetchGet(url) {
  return fetchWrapper(url, 'GET');
}

Вам не нужно async, если вы не используете await внутри функции. Вы можете использовать выберите, чтобы отметить асинхронный характер функции, например, в качестве документации в коде (подсказки по коду в IDE и т. д.). Но это не требуется.


Примечание: у вас проблема с fetchWrapper. Это преуспевает со значением выполнения undefined, если есть ошибка HTTP. Это означает, что код, использующий его, должен проверить значение выполнения, чтобы увидеть, является ли оно undefined, прежде чем использовать его. Я бы рекомендовал делать ошибки ошибок HTTP (отказы):

async function fetchWrapper(url, method) {
  const response = await fetch(url, {method: method});
  if (!response.ok) {
    throw new Error("HTTP error " + response.status);
  }
  return response;
}

«В противном случае он вам не нужен.» субъективная причина его использования заключается в том, что async дает понять, какая функция является асинхронной. Вам нужно только посмотреть на подпись, а не проверять, что делает код. На самом деле, с кодом OP fetchGet будет асинхронным, но вы должны следить за вызовом функции внутри него, чтобы увидеть это. Я не сомневаюсь, что есть автоматизированные инструменты, которые смогут извлекать подписи для вас, так что вам даже не нужно искать код самостоятельно, а значит, еще проще увидеть, что есть что.

VLAZ 22.05.2019 11:52

@ T.J.Crowder, ты прав с моей неуклюжей fetchWrapper, я слишком упростил ее. Я редактирую вашу краткую альтернативу

NicolasL 22.05.2019 12:00

Вам просто нужно объявить функцию как async, когда внутри функции вы собираетесь ожидать результата, поэтому оба:

// returns a Promise because it's async (resolved with 'value')
async function fetchGet(url) {
  const value = await fetchWrapper(url, 'GET');
  return value;
}

// returns a Promise because fetchWrapper is a Promise
function fetchGet(url) {
  return fetchWrapper(url, 'GET');
}

// returns a Promise, just because it's async
async function fetchGet(url) {
   // nothing
}

// returns undefined
function fetchGet(url) {
    // nothing 
}

Работайте точно так же для этих вызывающих абонентов:

fetchGet('url').then(value => {...})
const value = await fetchGet(url)

Другие вопросы по теме