📜  ES6-承诺

📅  最后修改于: 2020-10-25 10:45:34             🧑  作者: Mango


承诺语法

有关承诺的语法如下,其中,p是承诺对象提到的,决心是当许成功执行,应该调用并拒绝时的承诺遇到一个错误,应该调用该函数的函数。

let p = new Promise(function(resolve,reject){
   let workDone = true; // some time consuming work
      if(workDone){
      //invoke resolve function passed
      
      resolve('success promise completed')
   }
   else{
      reject('ERROR , work could not be completed')
   }
})

下面给出的示例显示了一个add_positivenos_async()函数,该函数异步将两个数字相加。如果传递正值,则将兑现承诺。如果传递负值,则承诺将被拒绝。

 

上面代码的输出将如下所述-

end
Handling success 30
Handling error NOT_Postive_Number_Passed

承诺链

当我们有一系列异步任务要一个接一个地完成时,可以使用承诺链。当一个承诺依赖于另一个承诺的结果时,承诺就被链接在一起。在下面的示例中显示

在下面的示例中, add_positivenos_async()函数异步添加两个数字,如果传递负值,则拒绝。当前异步函数调用的结果将作为参数传递给后续函数调用。注意,每个then()方法都有一个return语句。

 

以上代码的输出将如下所示-

end
first result 30
second result 60
third result 120

下面详细讨论了Promise对象的一些常用方法-

promise.all()

此方法对于汇总多个promise的结果很有用。

句法

下面提到了promise.all()方法的语法,其中, iterable是一个可迭代的对象。例如数组。

Promise.all(iterable);

下面给出的示例执行一系列异步操作[add_positivenos_async(10,20),add_positivenos_async(30,40),add_positivenos_async(50,60)] 。当所有操作完成后,诺言就完全解决了。

 

上面的代码输出如下:

end
30
70
110
all add operations done

promise.race()

该函数接受一个promise数组,并返回已解决的第一个promise。

句法

下面提到了promise.race()函数的语法,其中,iterable是一个可迭代的对象。例如数组。

Promise.race(iterable)

下面给出的示例采用异步操作数组[add_positivenos_async(10,20),add_positivenos_async(30,40)]

每当任何添加操作完成时,承诺都会得到解决。 Promise不会等待其他异步操作完成。

 

上面的代码输出如下:

end
one of them is done
30

承诺是在JavaScript(ES6的新功能)中实现异步编程的一种干净方法。在承诺之前,回调用于实现异步编程。让我们从使用回调了解异步编程及其实现开始。

了解回调

一个函数可以作为参数传递给另一个函数。此机制称为回调。回调在事件中将很有帮助。

以下示例将帮助我们更好地理解此概念。

 

在上面显示的notifyAll()方法中,通过发送SMS和发送电子邮件来进行通知。因此,notifyAll方法的调用者必须传递两个函数作为参数。每个函数承担一个职责,例如发送SMS和发送电子邮件。

成功执行上述代码后,将显示以下输出。

starting notification process 
Sms send .. 
Email send .. 
End of script 

在上述代码中,函数调用是同步的。这意味着UI线程将等待完成整个通知过程。同步呼叫变为阻塞呼叫。现在让我们了解非阻塞或异步调用。

了解AsyncCallback

考虑上面的例子。

要启用脚本,请对notifyAll()方法执行异步或非阻塞调用。我们将使用JavaScript的setTimeout()方法。默认情况下,此方法是异步的。

setTimeout()方法采用两个参数-

  • 回调函数。

  • 此方法将被调用之前经过的秒数。

在这种情况下,通知过程已包含超时。因此,将需要两秒钟的延迟,由代码设置。 notifyAll()将被调用,并且主线程像执行其他方法一样继续进行。因此,通知过程不会阻止JavaScript主线程。


成功执行上述代码后,将显示以下输出。

End of script 
starting notification process 
Sms send .. 
Email send .. 

如果有多个回调,代码看起来会很吓人。


通过引入承诺的概念,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’。 Promise构造函数首先接管函数的工作,以成功完成工作,而在发生错误的情况下,接管函数。

承诺通过使用resolve回调并传递结果(即n1 + n2)来返回计算结果

步骤1 -resolve(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

以下示例使用getSum()方法发出三个then()调用。

 

成功执行上述代码后,将显示以下输出。

该程序首先显示“脚本结尾”,然后依次显示调用getSum()方法的结果。

End of script  
11 
30 
70

这表明getSum()以异步方式或非阻塞方式调用。 Promise提供了一种处理回调的好方法。