2019第三发javascript
Promise是一个构造函数,本身身上有call、resolve、reject,原型上有then、catch等方法。 Promise 对象有如下两个特色。html
这与事件(Event)彻底不一样,事件的特色是,若是你错过了它,再去监听,是得不到结果的。java
var promise = new Promise(function(resolve, reject) {
setTimeout(function(){
console.log('完成')
resolve('随便什么东西')
}, 2000)
})
复制代码
相似这样,Promise的构造函数接受一个参数:函数。而且会传入两个参数resolve、reject,用来表示成功或者失败。git
通常状况会把promise放在一个函数中,当函数调用时候才会执行promise的操做。es6
function runAsync(){
var p = new Promise(function(resolve, reject){
//作一些异步操做
setTimeout(function(){
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
return p;
}
runAsync().then(function(data){
console.log(data);
//后面能够用传过来的数据作些其余操做
//......
});
复制代码
表面上看Promise只是简化层层的回调写法,实质上,Promise的精髓是状态
github
function runAsync1(){
var p = new Promise(function(resolve, reject){
//作一些异步操做
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 1000);
});
return p;
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
//作一些异步操做
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('随便什么数据2');
}, 2000);
});
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
//作一些异步操做
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('随便什么数据3');
}, 2000);
});
return p;
}
复制代码
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return runAsync3();
})
.then(function(data){
console.log(data);
});
复制代码
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return '直接返回数据'; //这里直接返回数据
})
.then(function(data){
console.log(data);
});
复制代码
reject的做用就是把Promise的状态置为rejected,这样咱们在then中就能捕捉到,而后执行“失败”状况的回调。promise
then方法能够接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。dom
var promise = new Promise((resolve, reject) => {
reject('失败')
})
promise.then((data) =>{
console.log('success:' + data)
},(reason) => {
console.log('error:' + reason);
})
复制代码
Promise除了then还有catch方法,他和then的第二个参数同样,用来指定reject的回调。可是他还有一个做用:当在执行resolve的回调时候,若是出现异常那么js不会卡死,而是会进入到catch方法中。
异步
当catch上面有处理reject的函数时候,会一级一级的处理,而不是直接跳到catch中。async
function getNumber(){
var p = new Promise(function(resolve, reject){
//作一些异步操做
setTimeout(function(){
var num = Math.ceil(Math.random()*10); //生成1-10的随机数
if(num<=5){
resolve(num);
}
else{
reject('数字太大了');
}
}, 2000);
});
return p;
}
getNumber()
.then(function(data){
console.log(data);
console.log(somedata); //此处的somedata未定义
}).then((data) =>{
console.log('success:' + data)
},(reason) => {
console.log('error:' + reason);
})
.catch(function(reason){
console.error(reason);
});
复制代码
Promise的all方法提供了并行执行异步操做的能力,而且在全部异步操做执行完后才执行回调。
Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
console.log(results);
});
复制代码
all => 谁跑的慢,以谁为准执行回调
race => 谁跑的快,以谁为准执行回调
Promise
.race([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
console.log(results);
});
复制代码
function requestImg(){
var p = new Promise(function(resolve, reject){
var img = new Image();
img.onload = function(){
resolve(img);
}
img.src = 'xxxxxx';
});
return p;
}
//延时函数,用于给请求计时
function timeout(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
reject('图片请求超时');
}, 5000);
});
return p;
}
Promise
.race([requestImg(), timeout()])
.then(function(results){
console.log(results);
})
.catch(function(reason){
console.log(reason);
});
复制代码
finally
方法用于指定无论 Promise 对象最后状态如何,都会执行的操做。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
复制代码
finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态究竟是fulfilled仍是rejected。这代表,finally方法里面的操做,应该是与状态无关的,不依赖于 Promise 的执行结果。
finally
本质上是then
方法的特例。
var promise=new Promise(function(resolve,reject){
try {
throw new Error('test');
}catch(e){
reject(e)
}
})
复制代码
var promise=new Promise(function(resolve,reject){
reject(new Error('test'));
})
promise.catch(function(e){
//something to deal with the error
console.log(e)
})
复制代码
catch方面里面还能够再抛错误,这个错误会被后面的catch捕获
var promise=new Promise(function(resolve,reject){
reject(new Error('test1'))
})
promise.catch(function(e){
console.log(e);
throw new Error('test2')
}).catch(function(e){
console.log(e)
})
// Error : test1
// Error : test2
复制代码
若是组成Promise.all的promise有本身的错误捕获方法,那么Promise.all中的catch就不能捕获该错误。
var p1=new Promise(function(resolve,reject){
reject(new Error('test1'))
}).catch(function(e){
console.log("由p1自身捕获",e);
})
var p2=new Promise(function(resolve,reject){
resolve();
})
var p=Promise.all([p1,p2]);
p.then(function(){
}).catch(function(e){
//在此处捕获不到p1中的error
console.log(e)
})
//由p1自身捕获 Error: test1
复制代码
在promise实例resolve以后,错误没法被捕获。
var promise=new Promise(function(resolve,reject){
resolve();
throw new Error('test');//该错误没法被捕获
})
promise.then(function(){
//
}).then(function(e){
console.log(e)
})
复制代码
无