在JavaScript的世界中,所有代码都是单线程执行的。
由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现:异步操作就是在将来的某个时间点触发一个函数调用。
Promise对象定义:
var promise = new Promise(function(resolve, reject){
//执行代码
business code...
//结果处理代码,承诺在将来的某个时刻执行resolve或reject
setTimeout(function(){
if (condition) {
resolve(); //承诺执行resolve
} else {
reject(); //承诺执行reject
});
}, 2000);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
这种“承诺将来会执行”的对象在JavaScript中称为Promise对象。
Promise对象执行:
p.then(resolveFunc).catch(rejectFunc); // 执行后根据结果执行承诺的resolveFunc或rejectFunc。
以上使用感觉跟ajax没什么区别,但是Promise有比ajax更方便的地方,比如ajax的嵌套异步地狱写法可以用Promise简单的串行化写法实现:
如:
$.ajax({
url:'url',
type:'get',
success:function(data){
handle1(data);
//嵌套ajax异步
$.ajax({
url:'url',
type:'get',
success:function(data){
handle2(data);
},
error:function(reason){
errorFunc(reason);
}
});
},
error:function(reason){
errorFunc(reason);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
这样嵌套两层代码就显得难以阅读了,Promise在实现同样的逻辑下代码更显简洁易读,上面ajax嵌套异步可以描述为:有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。
替换ajax嵌套异步的Promise写法:
var p = new Promise(function(resolve, reject){
$.ajax({
url:'url',
type:'get',
success:function(data){
handle1(data);
resolve(); //承诺执行resolve
},
error: reject() //承诺执行reject
});
});
function job2() {
$.ajax({
url:'url',
type:'get',
success:function(data){
handle2(data);
resolve(); //承诺执行resolve
},
error: reject() //承诺执行reject
});
};
p.then(job2).catch(rejectFunc);
function job3() {
$.ajax({
url:'url',
type:'get',
success:function(data){
handle3(data);
resolve(); //承诺执行resolve
},
error: reject() //承诺执行reject
});
};
p.then(job2).then(job3).catch(rejectFunc);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
总结:创建Promise对象时,其匿名函数的参数resolve,reject函数其实就是Promise对象承诺会执行的对象,这些对象可以灵活的通过.then()和.catch()方式传入,因为有了这样的承诺,Promise才可以用链式写法串起来执行。
当然,Promise还有并行执行异步任务Promise.all()方法和容错执行Promise.race()方法,具体参考廖雪峰的官方网站javascript教程。
可运行测试代码:
function handleResponse(response){
console.log(response);
}
function reject() {
console.log('error');
}
var ppp = new Promise(function(resolve, reject){
$.ajax({
url:"https://api.douban.com/v2/book/search?q=javascript&count=1",
type:'get',
dataType : "jsonp",
jsonp : 'callback',
jsonpCallback: 'handleResponse',
success:function(data){
//这里因为跨域所以由handleResponse处理data
console.log('job1 finish');
resolve(); //承诺执行resolve
},
error: reject //承诺执行resolve
});
});
function job2() {
$.ajax({
url:"https://api.douban.com/v2/book/search?q=javascript&count=1",
type:'get',
dataType : "jsonp",
jsonp : 'callback',
jsonpCallback: 'handleResponse',
success:function(data){
//这里因为跨域所以由handleResponse处理data
console.log('job2 finish');
//无后续任务的话,不需要承诺执行resolve
},
error: reject //承诺执行resolve
});
};
ppp.then(job2).catch(reject);