DanLevy.net

Ловушки Promise

Избегание типичных ошибок

Hero image for Ловушки Promise

Промисы работают не так, как обычные значения

Вы не можете вывести их значение, как большинство значений:

// Это не имеет смысла для промисов:
console.log(Promise.resolve(42));
// Нужно использовать интерфейс `.then`:
Promise.resolve(42).then(value => console.log(value));

Промисы не предупреждают вас об ошибке

Ну, типичная ошибка.

По ряду причин TC39 решил, что в .then и .catch можно передавать null. Например, вызов .then(null, null) допустим, а требуемое поведение — пропустить этот «шаг» в цепочке.

К несчастью, это делает очень простым допустить ошибку.

На примере

Посмотрим на небольшую задачу: какие из перечисленных вариантов выведут в console.log число 42?

// Option #1:
Promise.resolve(42).then(console.log());
// Option #2:
Promise.resolve(42).then(console.log);
// Option #3:
Promise.resolve(42).then(value => console.log(value));
// Option #4:
Promise.resolve(42)
.then(console.log())
.then(console.log);
Ответ

Ответ — #2, #3 и #4.

Почему? Рассмотрим типы того, что передано в .then():

var arg1 = console.log();
var arg2 = console.log;
var arg3 = value => console.log(value);
typeof arg1 === "undefined";
typeof arg2 === "function";
typeof arg3 === "function";

Все ещё интересно, как работает четвертый вариант?

Это фактически эквивалентно следующему коду:

// Option #4 - effectively
Promise.resolve(42)
.then(undefined) // это не влияет на значение, оно будет передано следующему `.then(fn)`
.then(console.log);