Promise是一个构造函数,自身有all、reject、resolve这几个眼熟的方法,原型上有then、catch等方法;
1、简单的例子:
function runAsuync(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("执行完成")
resolve("随便什么数据");
},2000)
});
return p;
}
runAsuync().then(function(data){
console.log(data);
})
//在runAsync()的返回上直接调用then方法,then接收一个参数,是函数,
并且拿到我们在runAsync中调用resolve时传的参数。运行这段代码,
会在2秒后输出执行完成,紧接着输出 随便什么数据;
Promise构造函数接收一个参数(函数),并且可以传入两个参数:resolve和reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。
其实这里成功和失败描述的不够准确,按标准讲:
resolve:是将Promise状态置为fullfiled;
rejiect:是将Promise状态置为rejected;
注意:在使用Promise的时候,一般是将其放置在函数中,需要的时候去执行这个函数即可(因为Promise会自己执行)
2、链式操作的用法
function s1(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("s1执行完成");
resolve("s1随便什么数据");
},2000)
})
return p;
}
function s2(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("s2执行完成");
resolve("s2随便什么数据");
},2000)
})
return p;
}
function s3(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("s3执行完成");
resolve("s3随便什么数据");
},2000)
})
return p;
}
function s4(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
console.log("s4执行完成");
resolve("s4随便什么数据");
},2000)
})
return p;
};
s1().then(function(data){
console.log(data);
return s2();
}).then(function(data){
console.log(data);
return s3();
}).then(function(data){
console.log(data);
return s4();
}).then(function(data){
console.log(data);
return "hello world";
}).then(function(data){
console.log(data);
return "世界,还好"
}).then(function(data){
console.log(data);
})
Promise的精髓是“状态”,用维护状态、传递状态的方式使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多
在then方法中,你可以直接return数据而不是Promise对象,在后面的then中就可以接收数据了
3、reject的使用
reject的作用是把Promise的状态置为rejected,这样我们在then中就能捕捉到,执行失败的回调函数
function s1(){
var p=new Promise(function(resolve,reject){
setTimeout(function(){
// console.log("s1执行完成");
let num=Math.ceil(Math.random()*10);
if(num > 5){
resolve(num);
}else{
reject("数据小了");
}
},2000)
})
return p;
}
s1().then(
function(data){//成功后执行的回调
console.log("resolve");
console.log(data);
},
function(reason,data){//失败后执行的回调
console.log("reject");
console.log(reason,data);
}
)
4、catch的用法
作用一:接收reject的回调
作用二:执行resolve回调的时候,如果报错了,就执行catch方法,并且不会在控制台报错,程序不会停止运行,并且会在catch里面打印出错误原因,有点类似try/catch组合语句的用法
function s(){
return new Promise(function(resolve,reject){
setTimeout(function(){
var num=Math.floor(Math.random()*10);
console.log("生成的num:"+num)
if(num<5){
resolve(num);
}else{
reject('数据大了:'+num);
}
},2000);
})
}
s()
.then(
function(data){
console.log('resolve');
console.log(data);
console.log(w)
},
function(data){
console.log("reject");
console.log(data);
// console.log(w)
}
)
.catch(function(data){
console.log("catch reject");
console.log(data);
})
5、 all、race的使用
注意:
all:是执行所有的
适用场景:
一些游戏累的素材比较多的应用,打开网页时,会预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完成后,再进行页面的初始化。
race:是执行最快的,谁跑的快执行谁
适用场景:进行超时判断等
function f1(){
return new Promise(function(resolve,reject){
setTimeout(function(){
let num=Math.floor(Math.random()*10);
if(true){
resolve('f1:'+num);
}else{
reject('f1数据大了');
}
},1000)
})
}
function f2(){
return new Promise(function(resolve,reject){
setTimeout(function(){
let num=Math.floor(Math.random()*10);
if(true){
resolve('f2:'+num);
}else{
reject('f2数据大了');
}
},2000)
})
}
function f3(){
return new Promise(function(resolve,reject){
setTimeout(function(){
let num=Math.floor(Math.random()*10);
if(true){
resolve('f3:'+num);
}else{
reject('f3数据大了');
}
},400)
})
}
// Promise
// .all([f1(),f2(),f3()])
// .then(function(results){
// console.log(results);//得到的results是一个数组,所有返回的数据都在这里
// })
Promise
.race([f1(),f2(),f3()])
.then(function(results){
console.log(results);//只得到返回的最快的数据
})
race应用场景 例如
//请求某个图片资源
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);
});
requestImg函数会异步请求一张图片,我把地址写为"xxxxxx",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。