Что нового в ECMAScript 2017 (ES8)

Асинхронные функции

Синтаксис

  • Объявление асинхронной функции: async function asyncFunc() {}
  • Выражение с асинхронной функцией: const asyncFunc = async function () {};
  • Метод с асинхронной функцией: let obj = { async asyncFunc() {} }
  • Стрелочная асинхронная функция: const asyncFunc = async () => {};

Оператор async

async function mainQuestion() {
return 42;
}
const result = mainQuestion();
console.log(result instanceof Promise);
// true
console.log('Начало');
mainQuestion()
.then(result => console.log(`Результат: ${result}`));
console.log('Конец');
Начало
Конец
Результат: 42
async function dumbFunction() {}
console.log('Начало');
dumbFunction()
.then(result => console.log(`Результат: ${result}`));
console.log('Конец');
Начало
Конец
Результат: undefined
async function asyncLog(message) {
console.log(message);
}
console.log('Начало');
asyncLog('Асинхронная функция');
console.log('Конец');
Начало
Асинхронная функция
Конец
async function timeout(message, time = 0) {
return new Promise(done => {
setTimeout(() => done(message), time * 1000);
});
}
console.log('Начало');
timeout('Прошло 5 секунд', 5)
.then(message => console.log(message));
console.log('Конец');
Начало
Конец
Прошло 5 секунд (_через 5 секунд_)
function timeout(message, time = 0) {
return new Promise(done => {
setTimeout(() => done(message), time * 1000);
});
}
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
async function randomMessage() {
const message = [
'Привет',
'Куда пропал?',
'Давно не виделись'
][rand(0, 2)];
return timeout(message, 5);
}
async function chat() {
const message = await randomMessage();
console.log(message);
}
console.log('Начало');
chat();
console.log('Конец');
Начало
Конец
Куда пропал?
console.log('Начало');
chat()
.then(() => console.log('Конец'));
console.log('Это еще не конец');

Оператор await

console.log('Начало');
await chat();
console.log('Конец');
// SyntaxError: Unexpected token, expected ;
function mainQuestion() {
return new Promise(done => done(42));
}
async function dumbAwait() {
const number = await mainQuestion();
console.log(number);
}
dumbAwait();
// 42
function mainQuestion() {
return 42;
}
async function dumbAwait() {
const number = await mainQuestion();
console.log(number);
}
dumbAwait();
// 42
async function dumbAwait() {
const number = await 42;
console.log(number);
}
dumbAwait();
// 42
  1. если вернулся промис: ждем промис, и возвращаем результат;
  2. если вернулся не промис: оборачиваем в Promise.resolve и дальше аналогично.
async function longTask() {
console.log('Синхронно');
await null;
console.log('Асинхронно');
for (const i of Array (10E6)) {}
return 42;
}
console.log('Начало');
longTask()
.then(() => console.log('Конец'));
console.log('Это еще не конец');
Начало
Синхронно
Это еще не конец
Асинхронно
Конец

Обработка ошибок

async function failPromise() {
return Promise.reject('Ошибка');
}
async function catchMe() {
try {
const result = await failPromise();
console.log(`Результат: ${result}`);
} catch (error) {
console.error(error);
}
}
catchMe();
// Ошибка

Применение

async function fetchAsync(url) {
const response = await fetch(url);
const data = await response.json();
return data;
}
async function getUserPublicMessages(login) {
const profile = await fetchAsync(`/user/${login}`);
const messages = await fetchAsync(`/user/${profile.id}/last`);
return messages.filter(message => message.isPublic);
}
getUserPublicMessages('spiderman')
.then(messages => show(messages));

Поддержка

Object.values и Object.entries

Object.entries()

Object.entries({ аты: 1, баты: 2 });
[ [ 'аты', 1 ], [ 'баты', 2 ] ]
Object.entries(['n', 'e', 't', 'o', 'l', 'o', 'g', 'y']);
[ [ '0', 'n' ],   
[ '1', 'e' ],
[ '2', 't' ],
[ '3', 'o' ],
[ '4', 'l' ],
[ '5', 'o' ],
[ '6', 'g' ],
[ '7', 'y' ] ]

Символы игнорируются

Object.entries({ [Symbol()]: 123, foo: 'bar' });
[ [ 'foo', 'bar' ] ]

Итерация по свойствам

let obj = { аты: 1, баты: 2 };
for (let [x,y] of Object.entries(obj)) {
console.log(`${JSON.stringify(x)}: ${JSON.stringify(y)}`);
}
"аты": 1
"баты": 2

Object.values()

Поддержка

На сегодняшний день Object.entries() и Object.values() поддерживаются основными браузерами.

«Висячие» запятые в параметрах функций

function randomFunc(
param1,
param2,
) {}
randomFunc(
'foo',
'bar',
);
let obj = {
имя: 'Иван',
фамилия: 'Петров',
};
let arr = [
'красный',
'зеленый',
'синий',
];

Поддержка

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

«Заглушки» для строк: достигаем нужной длинны

Интерфейс функции

str.padStart(желаемаяДлинна, [строкаЗаглушка]);
str.padEnd(желаемаяДлинна, [строкаЗаглушка]);
'я'.padStart(6, '~'); // '~~~~~я''прямо в цель'.padStart(15, '-->'); // '-->прямо в цель''пусто'.padEnd(10); // 'пусто     ''Ч'.padEnd(10, '0123456789'); // 'Ч012345678'

Поддержка

Прекрасная картина!

Функция Object.getOwnPropertyDescriptors()

const person = {
first: 'Ирвинг',
last: 'Гофман',
get fullName() {
return `Добрый день, мое имя ${first} ${last}`;
},
};
console.log(Object.getOwnPropertyDescriptors(person));
{ first: 
{ value: 'Ирвинг',
writable: true,
enumerable: true,
configurable: true },
last:
{ value: 'Гофман',
writable: true,
enumerable: true,
configurable: true },
fullName:
{ get: [Function: get fullName],
set: undefined,
enumerable: true,
configurable: true } }

Область применения

  1. Для копирования свойств объекта, в том числе геттеров, сеттеров, неперезаписываемых свойств.
  2. Копирование объекта. .getOwnPropertyDescriptor можно использовать в качестве второго параметра в Object.create().
  3. Создание кроссплатформенных литералов объектов с определенным прототипом.

Поддержка

Даже у IE все в порядке.

Разделение памяти и объект Atomics

  1. Повышается скорость обмена данными между воркерами.
  2. Координация между воркерами становится быстрее и проще (по сравнению с postMessage()).

Безопасный доступ к общим данным

Поддержка

У этой «обновки» пока все плохо с поддержкой. Надеемся, верим, ждем.
  • новая спецификация каждый год;
  • браузеры быстро внедряют нововведения;
  • рабочая группа состоит из представителей корпораций, что позволяет быстро обмениваться опытом внедрения и оперативно корректировать либо описательную, либо техническую части.

--

--

Frontend-дева. Верстаю, пишу и перевожу статьи, менторю, выступаю. Поддержать переводы: https://www.tinkoff.ru/sl/2QSPTULCQcC

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Workafrolic (±∞)

Workafrolic (±∞)

3.6K Followers

Frontend-дева. Верстаю, пишу и перевожу статьи, менторю, выступаю. Поддержать переводы: https://www.tinkoff.ru/sl/2QSPTULCQcC