Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

Объявление async function определяет асинхронную функцию, которая возвращает объект AsyncFunction.

Вы также можете  определить async-функции, используя  выражение async function.

Синтаксис

async function name([param[, param[, ... param]]]) {
   statements
}
name
Имя функции.
param
Имя аргумента, который будет передан в функцию.
statements
Выражение, содержащее тело функции.

Описание

После вызова функция async возвращает Promise. Когда результат был получен, Promise завершается, возвращая полученное значение.  Когда функция async выбрасывает исключение, Promise ответит отказом с выброшенным (throws) значением.

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

Ключевое слово await допустимо только в асинхронных функциях. В другом контексте вы получите ошибку SyntaxError.

Цель функций async/await упростить использование promises синхронно и воспроизвести некоторое действие над группой  Promises. Точно так же как Promises подобны структурированным callback-ам, async/await подобна комбинации генераторов и promises.

Примеры

Простой пример

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function add1(x) {
  const a = await resolveAfter2Seconds(20);
  const b = await resolveAfter2Seconds(30);
  return x + a + b;
}

add1(10).then(v => {
  console.log(v);  // prints 60 after 4 seconds.
});

async function add2(x) {
  const a = resolveAfter2Seconds(20);
  const b = resolveAfter2Seconds(30);
  return x + await a + await b;
}

add2(10).then(v => {
  console.log(v);  // prints 60 after 2 seconds.
});

Не путайте await и Promise.all

Функция add1 приостанавливается на 2 секунды для первого await и еще на 2 для второго. Второй таймер создается только после срабатывания первого. В функции add2 создаются оба и оба же переходят в состояние await. В результате функция add2 завершится скорее через две, чем через четыре секунды, поскольку таймеры работают одновременно. Однако запускаются они все же не паралелльно, а друг за другом - такая конструкция не означает автоматического использования Promise.all. Если два или более Promise должны разрешаться параллельно, следует использовать Promise.all.

Когда функция async выбрасывает исключение

async function throwsValue() {
    throw new Error('oops');
}
throwsValue()
    .then((resolve) => {
            console.log("resolve:" + resolve);
        },
        (reject) => {
            console.log("reject:" + reject);
        });
//prints "reject:Error: oops"
//or
throwsValue()
    .then((resolve) => {
        console.log("resolve:" + resolve);
    })
    .catch((reject) => {
        console.log("reject:" + reject);
    });
//prints "reject:Error: oops"

Перепись цепочки promise с использованием функции async

API, которое возвращает Promise, будет возвращать значение в цепочке, тем самым разбивая функцию на много частей. Рассматривая следующий код:

function getProcessedData(url) {
  return downloadData(url) // returns a promise
    .catch(e => {
      return downloadFallbackData(url) // returns a promise
    })
    .then(v => {
      return processDataInWorker(v); // returns a promise
    });
}

он может быть переписан с одним использованием функции async:

async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url); 
  } catch(e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

Заметьте, что пример выше не содержит await на return, потому что возвращаемое значение функции async неявно обернуто в Promise.resolve.

Спецификации

Specification Status Comment
ECMAScript Latest Draft (ECMA-262)
Определение 'async function' в этой спецификации.
Черновик Initial definition in ES2017.
ECMAScript 2017 (ECMA-262)
Определение 'async function' в этой спецификации.
Стандарт  

Поддержка браузерами

Update compatibility data on GitHub
КомпьютерыМобильныеServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome для AndroidEdge MobileFirefox для AndroidOpera для AndroidSafari on iOSSamsung InternetNode.js
Базовая поддержкаChrome Полная поддержка 55Edge Полная поддержка ДаFirefox Полная поддержка 52IE Нет поддержки НетOpera Полная поддержка 42Safari Полная поддержка 10.1WebView Android Полная поддержка ДаChrome Android Полная поддержка 55Edge Mobile Полная поддержка ДаFirefox Android Полная поддержка 52Opera Android Полная поддержка 42Safari iOS Полная поддержка 10.1Samsung Internet Android Полная поддержка 6.0nodejs Полная поддержка 7.6.0
Полная поддержка 7.6.0
Полная поддержка 7.0.0
Отключено
Отключено From version 7.0.0: this feature is behind the --harmony runtime flag.

Легенда

Полная поддержка  
Полная поддержка
Нет поддержки  
Нет поддержки
Пользователь должен сам включить эту возможность.
Пользователь должен сам включить эту возможность.

Смотрите также

Метки документа и участники

Обновлялась последний раз: nikolai-shabalin,