Рубрики
Без рубрики

Обещания в Node.js.

Обещание – это асинхронная функция «дающая свое слово», что значение будет возвращено позже. Введены в ES6 / ES2015, обещания предоставляют современную альтернативу обратным вызовам

Автор оригинала: Shadab Ansari.

Вступление

JavaScript это Однопоточный , что означает, что все, в том числе события, проходит по той же нити. Если нить не свободна, выполнение кода задерживается до тех пор, пока он не будет. Это может быть узкое место для нашего приложения, поскольку она действительно может вызвать серьезные проблемы с производительностью.

Есть разные способы, с помощью которых мы можем преодолеть это ограничение. В этой статье мы рассмотрим современный способ обрабатывать асинхронные задачи в JavaScript – Обещание с.

Обратные вызовы и обратный вызов ад

Если вы разработчик JavaScript, вы, вероятно, слышали о, если не используются, Обратные вызовы :

function hello() {
    console.log('Hello World!');
}

setTimeout(hello, 5000);

Этот код выполняет функцию, Setimeout () , что ждет определенного времени (в миллисекундах), передается ему как второй аргумент, 5000 Отказ После прохождения времени только тогда он выполняет функцию Привет , переданный ему как первый параметр.

Функция является примером Функция высшего порядка и функция, передаваемая ей, называется Обратный вызов – Функция, которая должна быть выполнена после другой функции, закончила выполнение.

Допустим, мы отправили запрос на API, чтобы вернуть самые любимые фотографии с нашей учетной записи. Возможно, мы можем дождаться ответа, поскольку API/Service может выполнять некоторые расчеты перед возвратом ответа.

Это может потенциально занять много времени, и мы не хотим заморозить нить, пока мы ждем ответа. Вместо этого мы создадим обратный вызов, который будет уведомлен, когда вступает в ответ.

До того времени остальная часть кода выполняется, например, представление постов и уведомлений.

Если вы когда-либо работали с обратными вызовами, есть шанс, который вы испытали обратный вызов ад:

doSomething(function(x) {
    console.log(x);
    doSomethingMore(x, function(y) {
        console.log(y);
        doRestOfTheThings(y, function(z) {
            console.log(z);
        });
    });
});

Представьте, что если мы запрашиваем сервер, чтобы получить несколько ресурсов – человек, их друзья и посты их друга, комментарии для постов каждого друга, ответы и т. Д.

Управление этими вложенными зависимостями могут быстро выйти из-под контроля.

Мы можем избежать обратного вызова ада и обращаться с асинхронными вызовами, используя Обещание с.

Создание обещания

Обещание S, как подразумевает имя, это функция «дает свое слово», что значение будет возвращено в более позднее время. Это прокси для значения, которое может не быть возвращено, если функция, которую мы ожидаем ответа не доставляют.

Вместо того, чтобы возвращать конкретные значения, эти асинхронные функции возвращают A Обещание Объект, который будет в какой-то момент либо выполняться или нет.

Чаще всего при кодировании мы будем потребляться Обещание вместо того, чтобы создать их. Это библиотеки/каркасы, которые создают Обещание S для клиентов, чтобы потреблять.

Тем не менее, хорошо понимать, что идет за создание Обещание :

let promise = new Promise(function(resolve, reject) {
    // Some imaginary 2000 ms timeout simulating a db call
    setTimeout(()=> {
        if (/* if promise can be fulfilled */) {
            resolve({msg: 'It works', data: 'some data'});
        } else {
            // If promise can not be fulfilled due to some errors like network failure
            reject(new Error({msg: 'It does not work'}));
        }
    }, 2000);
});

Конструктор обещания получает аргумент – обратный вызов. Обратный вызов может быть обычной функцией или функцией стрелки. Обратный вызов принимает два параметра – решить и Отклонить Отказ Оба функциональные ссылки. Обратный вызов также называется исполнителем.

Исполнитель работает сразу, когда будет создано обещание. Обещание решено, позвонив разрешать () Если обещание выполнено и отклонено призванию Отклонить () Если это не может быть выполнено.

Оба разрешать () и Отклонить () принимает один аргумент – логический , строка , Номер , массив или объект Отказ

Потребление обещания

Через API скажем, мы запросили некоторые данные с сервера и неясно, когда он будет возвращен – если это будет возвращено вообще. Это идеальный пример, когда мы будем использовать Обещание чтобы помочь нам.

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

promise.then((result) => {
    console.log("Success", result);
}).catch((error) => {
    console.log("Error", error);
})

Как мы видим, мы приложили два метода – тогда () и поймать () Отказ Это немногие из различных методов, предоставляемых Обещание объект.

тогда () выполняется, когда все идет хорошо, то есть обещание выполняется разрешать () метод. И если обещание было отклонено, поймать () Способ будет вызван с ошибкой, отправленной на Отклонить Отказ

Цепочка

Если у нас есть последовательность асинхронных задач один за другим, которая должна быть выполнена – тем более вложенность существует, тем больше запутается код.

Это приводит нас к обратному адму, который можно легко избежать, церовав несколько тогда () Методы на одном Обещание D Результат:

promise.then(function(result) {
    // Register user
    return {account: 'blahblahblah'};
}).then(function(result) {
    // Auto login
    return {session: 'sjhgssgsg16775vhg765'};
}).then(function(result) {
    // Present WhatsNew and some options
    return {whatsnew: {}, options: {}};
}).then(function(result) {
    // Remember the user Choices
    return {msg: 'All done'};
});

Как мы можем видеть, результат пропускается через цепочку тогда () обработчики:

  • Первоначальный Обещание Объект разрешается
  • Тогда тогда () Обработчик вызывается для регистрации пользователя
  • Значение, которое он возвращается, передается следующему тогда () Обработчик для автоматического входа пользователя
  • …и так далее

Кроме того, Затем (обработчик) может создать и вернуть обещание.

Примечание: Хотя технически мы может Сделайте что-то вроде примера разбирательства, он может забрать от точки цепочки. Хотя этот метод может быть хорошим для того, чтобы при необходимости вызовете асинхронные методы:

let promise = new Promise(function(resolve, reject) {
    setTimeout(() => resolve({msg: 'To do some more job'}), 1000);
});

promise.then(function(result) {
    return {data: 'some data'};
});

promise.then(function(result) {
    return {data: 'some other data'};
});

promise.then(function(result) {
    return {data: 'some more data'};
});

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

Таким образом, все обработчики получают один и тот же результат – результат этого обещания – {msg: «сделать еще больше работы»} Отказ

Заключение

Обещание s, как подразумевает имя, это функция «дает свое слово», что значение будет возвращено в более позднем моменте во времени. Это прокси для значения, которое может не быть возвращено, если функция, которую мы ожидаем ответа не доставляют.

Вместо того, чтобы возвращать конкретные значения, эти асинхронные функции возвращают A Обещание Объект, который будет в какой-то момент либо выполняться или нет.

Если вы работали с обратными вызовами, вы должны оценить чистую и прозрачную семантику Обещание с.

Как разработчик узла/JavaScript, мы будем иметь дело с обещаниями чаще. В конце концов, это асинхронный мир, полный сюрпризов.