promise使用总结
promise 是处理异步编程的一种处理方式,可以将异步操作按照同步操作的方式编写。是一个对象或者构造函数,里面存放着某个未来才会执行的结果的方法(一般就是异步操作)
自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。
* 优点
* 将异步操作以同步操作的流程表现出来,避免层层嵌套的回调函数
* 也有缺点 一但建立不能取消
* 其次如果不设置回调函数 内部会抛出报错,不会反应到外部
* 三 处于pending状态时候 无法得知目前处于哪个阶段
*
* 如果事件不断反复发生 使用stream模式比部署promise更好选择
两个特点
* 1 对象状态不受影响 内部有三种状态 pending fulfilled rejected
* 只有异步操作能决定当前的状态其他任何操作都无法改变状态
* 2状态一旦改变就不会再改变,任何时候都可以得到这个结果
* 会一直保持这个结果 resolved 已定型 再对promise对象添加回调函数还是会返回这个结果
* 与事件event不同 事件的特点如果你错过了事件调用 再去监听事件 是不会得到结果的
三种状态 pending fulfilled rejected
基本用法
promise对象是一个构造函数 可以生成promise实例 然后立即执行
promise 构造函数 接受一个函数作为参数 该函数有两个参数分别是 resolve *reject
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数。
Promise.prototype.then()
Promise 实例具有then
方法,也就是说,then
方法是定义在原型对象Promise.prototype
上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then
方法的第一个参数是resolved
状态的回调函数,第二个参数是rejected
状态的回调函数,它们都是可选的。
const promise = new Promise(function(reslove,reject){
if(/*异步操作成功*/){
resolve(value)
}else{
reject(error)
}
})
/*使用 new 实例化*/
promise.then(function(value){
//success
},function(err){
//failure
})
异步加载图片案例
function loadImageAsync(url){
return new Promise(function(reslove,reject){
const image = new Image();
image.onload = function (){
console.log('image suss')
reslove(image)
};
image.onerror = function (){
reject(new Error('could not load image at'+url))
};
image.src = url
})
}
const as =
let asyncimg = loadImageAsync('http://app.jbttech.com.cn/AppLogo/android/ic_launcher2_1.png')
asyncimg.then((res)=>{
console.log(res)
})
catch的用法
与Promise对象方法then方法并行的一个方法就是catch,与try catch类似,catch就是用来捕获异常的,也就是和then方法中接受的第二参数rejected的回调是一样的
function promiseRan(){
let p = new Promise(function(resolve, reject){
setTimeout(function(){
var rannum = parseInt(Math.random()*30);
if(rannum<=20){
resolve(num);
}
else{
reject('即将执行失败回调');
}
}, 2000);
})
return p
}
promiseRan().then(
function(data){
console.log('resolved成功回调');
console.log('成功回调接受的值:',data);
}
)
.catch(function(reason, data){
console.log('catch到rejected失败回调');
console.log('catch失败回调原因:',reason);
});
all的用法
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all()
方法接受一个数组作为参数,p1
、p2
、p3
都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve
方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()
方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
分两种情况
onst p = Promise.all([p1, p2, p3]);
1 p1 p2 p3 状态都为fulfilled p状态才为fulfilled 此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
2 p1 p2 p3 状态有一个为rejected p 状态为rejected 此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
function promise1(){
return new Promise((resolve, reject) => {
axios.post(url,params).then((res) => {
console.log('数据返回', res.data.msg)
resolve(res.data)
}).catch((err) => {
console.log('解析错误', err)
reject(error)
})
})
}
function promise2(){
return new Promise((resolve, reject) => {
axios.post(url,params).then((res) => {
console.log('数据返回', res.data.msg)
resolve(res.data)
}).catch((err) => {
console.log('解析错误', err)
reject(error)
})
})
}
function promise3(){
return new Promise((resolve, reject) => {
axios.post(url,params).then((res) => {
console.log('数据返回', res.data.msg)
resolve(res.data)
}).catch((err) => {
console.log('解析错误', err)
reject(error)
})
})
}
Promise.all([promise3(), promise2(), promise1()]).then(function(results){
console.log(results);
});
race的用法
all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。
function promise1(){
return new Promise(function(resolve, reject){
setTimeout(function(){
var num = parseInt(Math.random()*20);
if(num<=10){
resolve(num);
}
else{
reject('2失败回调');
}
}, 2000);
})
}
function promise2(){
return new Promise(function(resolve, reject){
setTimeout(function(){
var num =parseInt(Math.random()*20);
if(num<=10){
resolve(num);
}
else{
reject('3执行失败回调');
}
}, 3000);
})
}
function promise3(){
return new Promise(function(resolve, reject){
setTimeout(function(){
var num = parseInt(Math.random()*20);
if(num<=10){
resolve(num);
}
else{
reject('4即将执行失败回调');
}
}, 4000);
})
}
Promise
.race([promise3(), promise2(), promise1()])
.then(function(results){
console.log('成功',results);
},function(reason){
console.log('失败',reason);
});