Учебники

ES6 — Обещания

Обещания — это чистый способ реализации асинхронного программирования на 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 () вызывается в асинхронном или неблокирующем стиле. Обещание дает хороший и чистый способ справиться с обратными вызовами.