меню

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

Статья описывает три способа понимания промисов (обещаний). Ниже показан пример функции 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

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

Как избежать повторной загрузки контента Jquery + Ajax + JSON

Как избежать повторной загрузки контента Jquery + Ajax + JSON. Для работы Front - End'а доступны были по ТЗ только таковы инструменты Java Script, JQuery, Ajax, JSON и конечно же HTML + CSS.

Javascript array шпаргалка

Переменные в Javascript позволяют хранить только одни данные за раз. Однако, учитывая, что часто бывает полезно манипулировать большим количеством данных, концепции переменной иногда недостаточно, потому что становится трудно управлять большим количеством различных переменных.

Каррирование в JavaScript

В этой статье вы простым языком поймете работу с каррированием в JavaScript и увидите рабочие примеры его применения

Разрешаем только ввод цифр в поле input

Часто возникает задача запрета ввода не цифровых значений в поле input. В этом материале разберем реализацию данного механизма на JavaScript.