对于promise这个问题,咱先了解了解什么叫回调函数!
- 回调函数:其实就是把函数A作为函数B的参数,函数A叫作回调函数。
- 函数是个引用类型的变量,函数名就是变量名,跟数组是一样的
function a(cb) {
cb()
}
function b() {
console.log('我是函数 b')
}
a(b)
//我是函数 b
回调函数有什么用?
- 当我们执行一个异步的行为的时候,我们需要在一个异步行为执行完毕之后做一些事情
- 那么,我们是没有办法提前预知这个异步行为是什么时候完成的
- 我们就只能以回调函数的形式来进行
- 就比如我们刚刚封装过的那个 ajax 函数里面的 success
- 我们并不知道 ajax 请求什么时候完成,所以就要以回调函数的形式来进行
什么是promise?
-
Promise 是Es6对异步编程的一种解决方案,比传统的解决方案(回调函数)更合理更便捷更强大。
-
Promise简单来说就是一个容器,里边保这尚未完成且预计在未来完成的异步操作。
-
Promise对象代表一个异步操作,有三种状态:
pending(进行中)
fulfilled(已成功)
rejected(已失败) -
Promise 对象的状态改变有两种:
从 pending 变为 fulfilled
从 pending 变为 rejected -
一旦状态改变,就不会再变,任何时候都可以得到这个结果。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
创建Promise对象
var p1 = new Promise(function(resolve,reject){
// resolve 让promise对象从进行中变成 成功的状态
// reject 让promise对象从进行中变成 失败的状态
// resolve('成功');
reject('失败');
});
Promise实例对象的then方法
- then里面的第一个函数在状态为成功时执行的回调函数(必须带参数),第二函数在状态为失败时执行的回调函数(可选),方法返回的是一个新的Promise实例
Promise实例对象的catch方法,
- catch():当then方法中只有一个函数时,既可以检测then方法中的错误信息,也可以检测promise构造函数中的错误信息,当then方法中有两个函数时,只能检测then方法中的错误信息
注意:捕获的是then方法中的错误,而第二函数在状态为失败(reject)检测的是promise对象失败时候进行的
p1.then(function(msg){
// console.log(msg);//'成功'
console.lag(msg);//lag没写错,演示报错提示使用
},function(msg){
console.log(msg);
})
.catch(function(err){
console.log(err);
});
再来几个实例
例1:
setTimeout(function(){
console.log('程序1');
setTimeout(function(){
console.log('程序2');
setTimeout(function(){
console.log('程序3');
},3000);
},2000);
},1000);
//控制台先后打印程序1,程序2,程序3
封装后
function doSomething(msg,time){
return new Promise(function (resolve,reject){
setTimeout(function(){
console.log(msg);
resolve();
},time);
});
}
doSomething('程序1',1000)
.then(function(){
return doSomething('程序2',2000);//返回promise对象
})
.then(function(){
return doSomething('程序3',3000);//返回promise对象
})
.then(function(){
console.log('所有程序执行完成');
})
例2:
console.log(111)
var p1=new Promise(function(resolve,reject){
console.log(222)
resolve('hello world') //成功
// reject('哦豁') //代表请求失败
// alertt('hello')
});
p1.then(function(res){
console.log(res)
},function(err){
console.log(err)
})
console.log(333)
//打印结果先后 111,222,333,hello
Promise.all
Promise.all 可以将多个Promise实例包装成一个新的Promise实例。
执行要求
- 它接受一个数组作为参数。
- 数组可以是Promise对象,也可以是其它值,只有Promise会等待状态改变。
- 当所有的子Promise都完成,该Promise完成,返回值是全部值的数组。
- 如果有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果。
var p1=new Promise(function(resolve,reject){
resolve('成功1')
})
var p2=new Promise(function(resolve,reject){
reject('成功2')
})
var p3=new Promise(function(resolve,reject){
resolve('成功3')
})
Promise.all([p1,p2,p3]).then(function(data){
console.log(data)
},function(err){
console.log(err)
})
//结果:成功2