1、概述
es6提供了promise对象
Promise对象: 代表了未来将要发生的事件,用来传递异步操作的消息。
英文本意就是承诺,成功了就怎样,失败了再怎样,其中怎样是回调
2、特点
-
对象的状态不受外界影响
- pending状态(进行中)
- fulfilled状态(已成功)
- rejected状态(已失败)
-
一旦状态改变就不会再改变
- pending -> fulfilled
- pending -> rejected
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,
你再对 Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,
如果你错过了它,再去监听,是得不到结果的。
3、Promise优缺点
- 优点
- 异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
- 提供统一的接口,使得控制异步操作更加容
- 缺点
- 无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
- 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
- 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
5、对象方法
- then:成功
- catch:失败,错误捕捉
- constructor
- reslove
- 表示异步操作执行成功后的回调函数
- 其实这里用“成功”来描述并不准确,标准讲,resolve是将Promise的状态置为fullfiled
- reject
- 表示异步操作执行失败后的回调函数。
- 其实这里用“失败”来描述并不准确,标准讲,reject是将Promise的状态置为rejected。
- all:执行多个异步任务
- race:竞赛
- reslove
- finally
4、基本用法
promise创建
// 使用new调用Promise构造器进行实例化
// Promise构造函数接收一个函数作为参数,这个函数叫做执行函数,该函数有两个参数是resolve,reject(Js引擎提供)。
// 其中resolve函数的作用是当Promise对象状态转移到成功,调用resolve并将操作结果作为其参数传递出去;
// reject函数的作用是当Promise对象的状态变为失败时,将操作报出的错误作为其参数传递出去。
function greet(){
// 异步处理
// 当异步代码执行成功时,我们调用resolve(...),
// 当异步代码失败时调用reject(...)
var promise = new Promise(function(resolve,reject){
var greet = "hello world";
resolve(greet);
});
return promise;
}
//message的值是上面调用resolve()方法传入的值.
greet().then(message=>{
console.log(message);//hello world
})
注意:
创建一个promise对象会立即执行里面的代码,
为了更好的控制代码的运行,一般用函数来包裹,并将promise对象作为函数的返回值
function runAsync1(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
console.log('异步任务1执行完成');
resolve('函数1成功');
console.log('111');
}, 1000);
});
console.log('函数1:',p);
return p;
// 执行顺序
// 打印函数1、返回p、打印异步任务1、111、函数1成功
// 创建promise、执行promise,遇到setTimeout加入进程,执行打印和返回p
//进入到setTimeout,执行打印异步、遇到resolve也是加入到进程,先把当前函数执行完毕后再进行then回调
}
function runAsync2(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
console.log('异步任务2执行完成');
resolve('函数2成功');
}, 2000);
});
console.log('2p',p);
return p;
}
function runAsync3(){
var p = new Promise(function(resolve, reject){
setTimeout(function(){
console.log('异步任务3执行完成');
resolve('函数3成功');
}, 2000);
});
console.log('3p',p);
return p;
}
runAsync1() .then(function(data){
console.log(data);//打印resolve的参数
return runAsync2();
})
//返回的promise对象是runAsync2()的状态和结果
.then(function(data){
console.log(data);
return runAsync3();
})
.then(function(data){
console.log(data);
});
runAsync1() .then(function(data){
console.log(data);//打印resolve的参数
return runAsync2();
})
.then(function(data){
console.log(data);
});
//链式调用
// then方法里return 表示链式调用then,即执行完runAsync2函数后,才进入后面的then/catch
//打印结果
//1p、p、异步任务1执行完成、111、函数1成功
//2p、异步任务2执行完成(函数2成功不会被打印,因为没有关联的then了)
// return可以直接返回数据
//后面的then就可以拿到数据
runAsync1() .then(function(data){
console.log(data);//打印resolve的参数
runAsync2();
})
.then(function(data){
console.log(data);
});
//then里面没有return时,runAsync2和下面的then同时调用
//因为打印结果是
//1p、p、异步任务1执行完成、111、函数1成功
//2p、undefined、异步任务2执行完成
getNumber().then(
function(data){
console.log('resolved');
console.log(data);
},
function(reason, data){
console.log('rejected');
console.log(reason);
}
//then方法接受两个参数,resolve函数、reject函数
//.then((res)=>{})
//.then((res)=>{},(rej)=>{})
//.then(
// function(reslove){},
// function(reject){},
// )
//错误捕捉
//.catch(reject)
// 同then第二个参数一样,但是报错不会卡死,如果在reslove中报错会进入到这里
//链式调用里只要有错误发生则会进入最后一个的catch中,若想确认位置则可以才then的第二个参数函数中捕获错误的发生
);
.then返回的新promise的结果状态由什么决定
- 简单表达:由.then内执行的回调函数的返回结果来决定。
- 详细表达:
- 回调函数没有返回值:返回一个状态fulfilled,value为undefined的新promise实例对象
- 回调函数返回的是非promise的任意值:返回一个状态fulfilled,value为返回值的新promise实例对象
- 回调函数如果返回值是一个新的promise实例对象(这个实例对象状态改变以后再将状态结果向下一个then传递):则回调函数返回的promise对象的结果就会成为.then返回的新promise的结果
- 回调函数如果抛出异常(throw new Error('error')):返回一个状态rejected,reason为抛出的异常值( new Error()内的值)的新promise实例对象
promise其他方法
1、Promise.all 处理多个异步的并行任务
Promise.all接收一个promises数组,并创建一个新的promise对象,
当数组的所的promise对象均成功时,该promise对象返回成功状态,否则返回失败状态
Promise.all([promise1,promise2]).then(result=>{
result[0]、result[1]、result[2]、
//当所有异步任务都成功时..
})
// result返回数组,所有返回成功状态的promise对象,数组排序对应all方法里的排序
2、Promise.race 竞赛
使用Promise.race方法并传入一个promise数组会返回一个新的promise对象,数组里第一个被处理的promise对象的状态就是该方法返回的状态,无论是成功或者拒绝
生成器和promise对象结合
面向未来的async函数 略