Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。
简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:
f1().then(f2);
以下结合具体分析:
(当要实现一下比如开始,进行,完成。)
setTimeout(function(){
console.log('开始')
},1000)
setTimeout(function(){
console.log('进行中')
},800)
setTimeout(function(){
console.log('完成')
}200)
//这样肯定不能实现,打印顺序是完成,进行中,开始。
如果要实现可能要进行嵌套:
setTimeout(function(){
console.log('开始')
setTimeout(function(){
console.log('进行中')
setTimeout(function(){
console.log('完成')
}200)
},800)
},1000)
要解决这种嵌套:
var p1 =new Promise(
function(resolve,reject){
setTimeout(function(){
console.log('开始')
resolve()
},1000)
})
p1.then(function(){
var p2=new Promise(function(resolve,reject){
setTimeout(function(){
console.log('进行中')
resolve()
},800)
})
return p2
}).then(function(){
setTimeout(function(){
console.log('完成')
},200)
})
//执行结果开始,进行,完成
封装:
function timeout(time){
return new Promise((resolve,reject)=>{
//setTimeout(()=>{
// resolve()
//},time)
setTimeout(resolve,time)
})
}
timeout(1000).then(function(){
console.log('开始')
return timeout(800)
}).then(function(){
console.log('进行中')
return timeout(200)
}).then(function(){
console.log('完成')
})
这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。
promise结合ajax:
例子:
function ajax(url){
return new Promise((resolve,reject)=>{
if(window.XMLHTTPRequest){
var xhr=new XMLHTTPRequest()
}else{
var xhr=new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('get',url,true);
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.states==200){
var data=xhr.responseText
resolve(data)
}
}
}
})
}
ajax('data1.json').then(function(data){
console.log(data)
return ajax('data2.json')
}).then(function(data){
console.log(data)
return ajax('data3.json')
}).then(function(data){
console.log(data)
})
//打印结果[1],[2],[3]
promise的方法:
除了串行执行若干异步任务外,Promise还可以并行执行异步任务
all(手牵手)和race(赛跑)
all:当数据都请求成功,开始处理
race:当其中一个数据请求成功,就开始处理
function timeout(time){
return new Promise((resolve,reject)=>{
setTimeout(resolve,time)
})
}
var p1=timeout(5000)
var p2=timeout(2000)
var p3=timeout(1000)
//Promise.all([p1],[p2],[p3]).then(function(){
// console.log('aa')
// }) //这个是谁跑的慢,以谁的时间为准
Promise.rece([p1],[p2],[p3]).then(function(){
console.log('aa')
})//这个是谁跑的快,以谁的时间为准
all适用场景: 一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是可以并行执行的,用Promise.all()实现如下:
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
race适用场景: 有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
由于p1执行较快,Promise的then()将获得结果’P1’。p2仍在继续执行,但执行结果将被丢弃。
如果我们组合使用Promise,就可以把很多异步任务以并行和串行的方式组合起来执行。