меню

Три способа понять промисы

Статья описывает три способа понимания промисов (обещаний). Ниже показан пример функции asyncFunc(), основанной на промисах:

  
function asyncFunc() {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve('DONE'), 100);
    });
}
asyncFunc()
.then(x => console.log('Result: '+x));
    
// Output:
// Result: DONE
 

Так что такое промис?

  • Технически, вызов asyncFunc() - это блокирующий вызов функции.
  • Промис — это одновременно и контейнер для значения и эмиттер событий.

Вызов Promise-based функции является блокирующим

  
function asyncFunc() {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve('DONE'), 100);
    });
}
async function main() {
    const x = await asyncFunc(); // (A)
    console.log('Result: '+x);
    
    // Same as:
    // asyncFunc()
    // .then(x => console.log('Result: '+x));
}
main();
 

Функция main() - это асинхронная функция. Ее тело показывает, что происходит концептуально — как мы обычно думаем об асинхронных вычислениях:

Строка (А): Ждет пока выполнится asyncFunc().
Строка (B): Выводит результат x в консоль.

До ECMAScript 6 и генераторов вы не могли приостанавливать и возобновлять код, поэтому с помощью промисов вы помещаете все, что происходит после возобновления кода, в коллбэк. Вызов этого коллбэка аналогичен возобновлению кода.

Промис — это контейнер для асинхронно возвращаемого значения

Если функция возвращает промис, то этот промис похож на пустое значение, которое функция (как правило) в конечном итоге заполнит результатом, как только вычислит его. Вы можете смоделировать простую версию этого процесса через массив:

  
function asyncFunc() {
    const blank = [];
    setTimeout(() => blank.push('DONE'), 100);
    return blank;
}
const blank = asyncFunc();
// Wait until the value has been filled in
setTimeout(() => {
    const x = blank[0]; // (A)
    console.log('Result: '+x);
}, 200);
 

С промисами вы не получаете доступ к конечным значениям с помощью [] (как в строке (А)), а используете метод then() и функцию обратного вызова.

Промис — это эмиттер событий

Другой способ взглянуть на промис — как на объект, который генерирует события.

  
function asyncFunc() {
    const eventEmitter = { success: [] };
    setTimeout(() => { // (A)
        for (const handler of eventEmitter.success) {
            handler('DONE');
        }
    }, 100);
    return eventEmitter;
}
asyncFunc()
.success.push(x => console.log('Result: '+x)); // (B)
 

Регистрация слушателя событий (строка (B)) может быть выполнена после вызова asyncFunc(), так как коллбэк, переданный в setTimeout() (строка (A)) выполняется асинхронно, после того, как выполнится сама функция.

Обычные эмиттеры событий порождают несколько событий, начиная с момента регистрации.

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

Оригинал статьи был взят с сайта getinstance.info

Помощь сайту
ЮMoney:
4100 1180 7209 833
Карта Сбербанк:
2202 2080 6183 7127

Возможно, вам будет интересно

Как исправить ошибку «RangeError: Invalid time value» при вызове метода toISOString даты JavaScript?

В этой статье мы рассмотрим, как исправить ошибку «RangeError: Invalid time value» при вызове toISOString метода даты JavaScript.

Видео самоучитель jQuery от Envato

Видео курс от компании Envato, Видео курс на английском языке. jQuery - это библиотека, которая значительно упрощает и ускоряет написание JavaScript кода. Видео курс самоучителя jQuery позволит Вам научится работать на нем. Пройдя данный курс Вы научитесь основам работы с jQuery!

This в JavaScript

Ключевое слово this в JavaScript, так же, как и во многих других языках программирования, используется подобно местоимению в естественном языке. Так же, как в естественном языке, с помощью местоимений мы указываем на определенного человека, животное, предмет, в JavaScript мы можем использовать this для указания на определенный объект.

Перестаньте всё превращать в массивы (и работайте меньше)

Большая часть фронтенд-кода обрабатывает данные задолго до их вывода на экран. Мы получаем список, изменяем его, сокращаем и повторяем. И обычно не задумываемся о том, какой объём работы выполняем на этом пути.