Promise
说起Promise,我们需要先把JavaScript回调地狱的问题理清楚!
看如下代码:
var sayhello = function (name, callback) {
setTimeout(function () {
console.log(name);
callback();
}, 1000);
}
sayhello("first", function () {
sayhello("second", function () {
sayhello("third", function () {
console.log("end");
});
});
});
//输出: first second third end
回调函数就是将某个函数当作参数供另一个函数执行使用,在该函数体内特定的位置特定的时间去调用,而被当做参数传递至该函数体内的函数同样也可以接受另外的函数当参数并在函数体内调用,接着,该另外的函数同样也能再接受一个函数当参数…一层一层嵌套,无穷无尽,由此也就进入回调地狱内,该用法的弊端就是:程序可读性差、可维护性不足;而且中间执行的时候,如果出现异常,则无法顺利进入下一步,造成程序阻塞。
因此,在新的ES6语法中,promise便产生了。
在jquery库中也有自己关于promise的实现方式,具体的使用,下面介绍
promise从字面意思看,有承诺、许诺的意思,意思就是使用了Promise之后肯定会给答复,无论成功或者失败都会给我们一个答复,所以不用担心迷失。在JavaScript的ES6语法中,Promise是一个对象,是用来处理异步操作及解决前面的程序回调地狱问题。所以,Promise有三种状态:pending(进行中),resolved(完成),rejected(失败)。只有异步返回的结构可以改变其状态。所以,promise的过程一般只有两种:pending->resolved或者pending->rejected。
promise对象还有一个比较常用的then方法,用来执行回调函数,then方法接受两个参数,第一个是成功的resolved的回调,另一个是失败rejected的回调,第二个失败的回调参数可选。并且then方法里也可以返回promise对象,这样的话就可以进行链式调用了。
Promise的三种状态解析
Promise对象代表一个异步操作,其不受外界影响,其三个状态为:
·Pending(进行中、未完成的)
·Resolved(已完成,又称Fulfilled)
·Rejected(已失败)
new Promise((resolve,reject) => {
...
// 当需要回复成功、执行完毕消息时,
resolve(...);
// 当需要回复失败或者拒绝消息的时候
reject(...)
})
其中,pending代表正在进行中、还未完成。
使用Promise的好处
1.解决回调地狱(Callback Hell)问题
如果使用promise,代码会更加扁平且可读。then返回一个promise,因此我们可以将then的调用不停地串起来,其中then返回的promise装载了由调用返回的值。
firstAsync().then(function(data){
return secondAsync();
}).then(function(data2){
return thirdAsync();
}).then(function(data3){
//...
})
2.更好地进行错误捕获
多重callback除了会造成上面所述的代码层层嵌套问题,还会造成无法捕获异常或异常捕获不可控。
如下代码:
function fetch(callback){
setTimeout(()=>{
throw Error('Error')
},2000);
}
try{
fetch(() => {
console.log('请求处理');
})
}catch(error){
console.log('触发异常',error);// 永远不会触发
}
如果使用promise的话,通过reject的方法把promise的状态设置为rejected,这样我们在then中就能捕捉到,然后执行’失败’情况的回调。
注:then(fn1,fn2)中fn1为成功执行的函数,fn2为失败执行的函数
function fetch(callback){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('请求失败');
},2000)
})
}
fetch()
.then(
function(data){
console.log(data);
},
function(reason,data){
console.log('触发异常');
console.log(reason);
}
);
catch方法中处理reject的回调也是可以的
function fetch(callback){
return new Promise(()=>{
setTimeout(()=>{
reject('请求失败');
},2000);
})
}
fetch().then(
function(data){
console.log(data);
}
).catch(function(reason){
console.log('触发异常');
console.log(reason);
});
以上是关于错误捕获,下面是关于Promise的常见用法。
Promise使用详解(es6 promise)
then()方法
简单来讲,then 方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。
而 Promise 的优势就在于这个链式调用。我们可以在 then 方法中继续写 Promise 对象并返回,然后继续调用 then 来进行回调操作。
//做饭
function cook(){
console.log('开始做饭。');
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('做饭完毕!');
resolve('鸡蛋炒饭');
}, 1000);
});
return p;
}
//吃饭
function eat(data){
console.log(<