ES6 Promises
ES6 Promises
Promises是在JavaScript(ES6新功能)中实现异步编程的一种简洁的方法。在Promises之前,回调被用于实现异步编程。让我们开始了解异步编程是什么。
理解回调
函数可以作为参数传递给另一个函数。这种机制被称为回调。
下面的例子将帮助我们更好地理解这个概念。
<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
在上面提到的代码中,函数调用是同步的。这意味着UI线程将等待完成整个通知过程。同步调用成为阻塞调用。让我们现在理解非阻塞或异步调用。
理解异步回调
考虑上面的例子。
为了实现这样的功能,执行异步或非阻塞调用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通过引入Promises的概念来实现你的需求。Promises是“继续事件”,它们帮助您以更简洁的代码风格一起执行多个异步操作。
例子
让我们用一个例子来理解这一点。以下是语法。
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实现Promise的第一步是创建一种使用Promise的方法。让我们在这个示例中说明,getSum()方法是异步的,即它的操作不应阻止其他方法的执行。此操作完成后,它将稍后通知调用方。
下面的示例(步骤1)声明了一个承诺对象“var promise”。Promise构造函数首先用于成功完成工作,另一个是在发生错误时。
Promise通过使用解析回调和传递结果,即n1 +N2,返回计算结果
Step 1 − resolve(n1 + n2);
如果getSum()遇到错误或意外情况,它将在Promise中调用拒绝回调方法,并将错误信息传递给调用者。
Step 2 − reject(Error("Negatives not supported"));该方法的实现在下面的代码(步骤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()调用。
<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>在成功执行上述代码时显示以下输出。
该程序首先显示“end of script”,然后是调用getSum()方法的结果,一个接一个。
End of script 11 30 70
这显示了getsum ()在异步样式或非阻塞样式中调用。承诺提供了一种很好的和干净的方式来处理回调。