Promise是一个构造函数,自己有
all
resolve
reject
方法,原型上有.then
.catch
方法
下面是一个例子
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log('执行完成');
resolve('成功了!!!!!');
//reject('失败了!!!!!')
},1000)
});
我们直接打开浏览器 可以看到在页面中会有输出 执行完成
,但是我们并没有去调用这个函数,表明我们传入进去这个函数的时候就已经调用了,所以为了避免这个情况,我们就是将这个promise
放在一个函数里面,需要的时候再调用。
function testPromise(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log('执行完成');
resolve('成功了!!!!!');
//return 也可以代替resolve的作用,作为.then的回调函数的值
//reject('失败了!!!!!')
},1000)
});
return p;
}
testPromise();
写到这里其实就有两个疑问了,为什么要包装这么一个函数?以及我们如何拿到resolve
和reject
的值
then与catch
在之前说过原型上有.then
和.catch
方法,.then
是用来接收resolve
的数据,.catch
是用来接收reject
数据的。
testPromise().then(function(data){
//这个data就是 上面函数 resolve的内容
console.log(data)//成功了!!!!!
})
testPromise().catch(function(error){
//这个data就是 上面函数 reject的内容
console.log(error)//失败了!!!!!
})
以下是一个完整的例子
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('数字太大了');
}
}, 0);
});
return p;
}
getNumber().then(function(data) {
console.log('resolved');
console.log(data);//输出的就是 resolve==> num的值
}).catch(function(error){
console.log(error)//输出的是 reject =>> “数字太大了”
})
如果随机生成的数字大于5就会被catch
到,并且输出reject
的结果。
但是如果在.then
的回调里面抛出了一个异常,并不是卡死整个js 而是进入.catch
回调中来,这也是.catch
的另外一个作用
getNumber().then(function(data) {
console.log('resolved');
console.log(data);
console.log(somedata); //此处的somedata未定义
}).catch(function(error){
console.log('reject');
console.log(error)
})
在控制台中会显示
Promise.all的使用
首先我们来写一个链式操作
function runAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('随便什么数据1');
}, 2000);
});
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);
});
那么在控制台中的打印结果就是
每隔两秒就输出一个data
如果采用all
的方法,会发生什么事情呢?
Promise.all([runAsync1(),runAsync2(),runAsync3()]).then(function(results){
console.log(results)
})
所以在控制台中打印的结果就是
值得注意的一点就是,返回的
results
是一个数组。并且将这三个延时器并排进行了(不需要像上面等待六秒看到全部的结果)
Promise.race的使用
我们在使用Promise.all
方法的时候,我们会收到每个setTimeout
打印的值以及resolve
的值,叫做「谁跑的慢,以谁为准执行回调」,那么Promise.race
的作用就是「谁跑的快,以谁为准执行回调」。
Promise.race([runAsync1(),runAsync2(),runAsync3()]).then(function(results){
console.log(results)
})
并且我们将runAsync
里面的setTimeout
的时间一次修改为了 1000 2000 3000
可以看到除了
runAsync1
的resolve
输出,其他的都没有输出,但是函数还是执行了。
网友评论