Обещания — это чистый способ реализации асинхронного программирования на JavaScript (новая функция ES6). До обещаний Callbacks использовались для реализации асинхронного программирования. Давайте начнем с понимания того, что такое асинхронное программирование и его реализация с использованием обратных вызовов.
Понимание обратного вызова
Функция может быть передана в качестве параметра другой функции. Этот механизм называется обратным вызовом . Обратный звонок будет полезен в событиях.
Следующий пример поможет нам лучше понять эту концепцию.
<script> function notifyAll(fnSms, fnEmail) { console.log('starting notification process'); fnSms(); fnEmail(); } notifyAll(function() { console.log("Sms send .."); }, function() { console.log("email send .."); }); console.log("End of script"); //executes last or blocked by other methods </script>
В методе notifyAll (), показанном выше, уведомление отправляется с помощью SMS и электронной почты. Следовательно, вызывающий метод notifyAll должен передать две функции в качестве параметров. Каждая функция берет на себя одну ответственность, такую как отправка SMS и отправка электронной почты.
Следующий вывод отображается при успешном выполнении вышеуказанного кода.
starting notification process Sms send .. Email send .. End of script
В упомянутом выше коде вызовы функций являются синхронными. Это означает, что поток пользовательского интерфейса будет ожидать завершения всего процесса уведомления. Синхронные звонки становятся блокирующими звонками. Давайте разберемся с неблокирующими или асинхронными вызовами.
Понимание AsyncCallback
Рассмотрим приведенный выше пример.
Чтобы включить сценарий, выполните асинхронный или неблокирующий вызов метода notifyAll (). Мы будем использовать метод JavaScript setTimeout () . Этот метод является асинхронным по умолчанию.
Метод setTimeout () принимает два параметра:
-
Функция обратного вызова.
-
Количество секунд, после которого будет вызван метод.
Функция обратного вызова.
Количество секунд, после которого будет вызван метод.
В этом случае процесс уведомления был обернут тайм-аутом. Следовательно, это займет две секунды задержки, установленной кодом. Будет вызываться notifyAll (), и основной поток продвигается вперед, как и при выполнении других методов. Следовательно, процесс уведомления не будет блокировать основной поток JavaScript.
<script> function notifyAll(fnSms, fnEmail) { setTimeout(function() { console.log('starting notification process'); fnSms(); fnEmail(); }, 2000); } notifyAll(function() { console.log("Sms send .."); }, function() { console.log("email send .."); }); console.log("End of script"); //executes first or not blocked by others </script>
Следующий вывод отображается при успешном выполнении вышеуказанного кода.
End of script starting notification process Sms send .. Email send ..
В случае нескольких обратных вызовов, код будет выглядеть страшно.
<script> setTimeout(function() { console.log("one"); setTimeout(function() { console.log("two"); setTimeout(function() { console.log("three"); }, 1000); }, 1000); }, 1000); </script>
ES6 приходит на помощь, вводя концепцию обещаний. Обещания являются «событиями продолжения», и они помогают вам выполнять несколько асинхронных операций вместе в гораздо более чистом стиле кода.
пример
Давайте разберемся с этим на примере. Ниже приводится синтаксис для того же.
var promise = new Promise(function(resolve , reject) { // do a thing, possibly async , then.. if(/*everthing turned out fine */) resolve("stuff worked"); else reject(Error("It broke")); }); return promise; // Give this to someone
Первым шагом к выполнению обещаний является создание метода, который будет использовать обещание. Допустим, в этом примере метод getSum () является асинхронным, т. Е. Его работа не должна блокировать выполнение других методов. Как только эта операция завершится, она позже сообщит об этом вызывающей стороне.
В следующем примере (шаг 1) объявляется объект Promise «var обещание». Конструктор Promise сначала выполняет функции для успешного завершения работы, а другой — в случае ошибки.
Обещание возвращает результат вычисления, используя обратный вызов разрешения и передавая результат, т.е. n1 + n2
Шаг 1 — решить (n1 + n2);
Если getSum () обнаруживает ошибку или непредвиденное условие, он вызывает метод обратного вызова в Promise и передает информацию об ошибке вызывающей стороне.
Шаг 2 — отклонить (Ошибка («Негативы не поддерживаются»));
Реализация метода приведена в следующем коде (ШАГ 1).
function getSum(n1, n2) { varisAnyNegative = function() { return n1 < 0 || n2 < 0; } var promise = new Promise(function(resolve, reject) { if (isAnyNegative()) { reject(Error("Negatives not supported")); } resolve(n1 + n2) }); return promise; }
Второй шаг подробно описывает реализацию вызывающей стороны (ШАГ 2).
Вызывающая сторона должна использовать метод then, который принимает два метода обратного вызова — первый для успеха и второй для сбоя. Каждый метод принимает один параметр, как показано в следующем коде.
getSum(5, 6) .then(function (result) { console.log(result); }, function (error) { console.log(error); });
Следующий вывод отображается при успешном выполнении вышеуказанного кода.
11
Так как тип возвращаемого значения getSum () — Promise, мы можем фактически иметь несколько операторов then. Первый ‘then’ будет иметь оператор return.
getSum(5, 6) .then(function(result) { console.log(result); returngetSum(10, 20); // this returns another promise }, function(error) { console.log(error); }) .then(function(result) { console.log(result); }, function(error) { console.log(error); });
Следующий вывод отображается при успешном выполнении вышеуказанного кода.
11 30
В следующем примере выполняется три вызова then () с методом getSum ().
<script> function getSum(n1, n2) { varisAnyNegative = function() { return n1 < 0 || n2 < 0; } var promise = new Promise(function(resolve, reject) { if (isAnyNegative()) { reject(Error("Negatives not supported")); } resolve(n1 + n2); }); return promise; } getSum(5, 6) .then(function(result) { console.log(result); returngetSum(10, 20); //this returns another Promise }, function(error) { console.log(error); }) .then(function(result) { console.log(result); returngetSum(30, 40); //this returns another Promise }, function(error) { console.log(error); }) .then(function(result) { console.log(result); }, function(error) { console.log(error); }); console.log("End of script "); </script>
Следующий вывод отображается при успешном выполнении вышеуказанного кода.
Программа сначала отображает «конец скрипта», а затем результат вызова метода getSum (), один за другим.
End of script 11 30 70
Это показывает, что getSum () вызывается в асинхронном или неблокирующем стиле. Обещание дает хороший и чистый способ справиться с обратными вызовами.