Должна ли функция быть объявлена ​​асинхронной, чтобы вернуть обещание? - PullRequest
3 голосов
/ 22 мая 2019

Я использую вспомогательную функцию (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');
}

Ответы [ 3 ]

4 голосов
/ 22 мая 2019

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

Нет, совсем нет.Фактически, обещания были сделаны задолго до того, как 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;
}
1 голос
/ 22 мая 2019

Вам просто нужно объявить функцию как 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)
1 голос
/ 22 мая 2019

Нужно ли объявлять эту вспомогательную функцию как асинхронную для самого себя, возвращая обещание?

Нет.

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

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

...