首先,让我们认识一下什么是Promise: 所谓Promise,就是一个对象,用来传递异步操作的消息,它代表了某个未来才会知道结果的事件。
听起来有些不知所谓,那么首先,console一下吧~
console.dir(Promise)
可以看出它是一个构造函数,拥有accept、all等属性,prototype中有catch、chain、then等方法,这意味着其实例也将拥有这些方法~
接下来创建一个试试
var p = new Promise(function(resolve, reject){
//异步操作
setTimeout(function(){
console.log('完成');
resolve('回调结果');
}, 2000);
});
解析:
Promise构造函数接受一个函数作为参数,该函数有两个参数resolve和reject
Promise对象有3种状态: Pending(进行中)、Resolved(已完成,又叫Fulfilled)、Rejected(已失败),
如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从 pending 变为 resolved;
如果异步操作失败,则用 reject 方法将 Promise 对象的状态,即从 pending 变为 rejected。
运行结果:两秒后输出 “完成”
由此发现一个问题:我们只是创建了一个实例,并未调用它!因此Promise实例创建时就运行了!因此一般做法是将其包在一个函数当中,需要时进行调用:
function runasync(){
var p = new Promise(function(resolve, reject){
//异步操作
setTimeout(function(){
console.log('完成');
resolve('回调结果');
}, 2000);
});
return p;
};
//调用
runasync();
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接下来是相关方法的使用:
then()
then接受一个函数或两个函数作为参数,第一个函数有data参数,data就是resolve传入的参数,第二个有err参数,err是reject传入的参数(resolve和reject都会进去)
eg: runasync().then(function(data){console.log(data)}); //输出完成 回调结果
于是乎我们将异步操作的结果传递过来,回调函数可在函数外部链式执行!
当然,如果只有一步异步操作,体现不出Promise的精华,但若有多个异步操作,Promise将省去大量代码!
eg:
function runasync(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('完成'); resolve('回调结果'); }, 2000); }); return p; }; function runasync1(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('完成'); resolve('回调结果1'); }, 2000); }); return p; }; function runasync2(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('完成'); resolve('回调结果2'); }, 2000); }); return p; }; runasync().then(function(data){ console.log(data);
//注意return return runasync1(); }) .then(function(data){ console.log(data); return runasync2(); });
输出:
完成
回调结果
完成
回调结果1
完成
catch()
catch与then的第二个参数一样,专门用来指定reject情况下的操作,但它有一种特殊用法:
如果resolve的回调(也就是then)出现异常,在其后面接上catch,就不会卡死js,而是会进入catch方法中。
eg:
function runasync(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('失败'); resolve("11"); }, 2000); }); return p; }; runasync().then(function(data){
//d未定义,一般情况下会报错,但接上catch不会 console.log(d); }).catch(function(err){ console.log(err); })
输出:
失败
ReferenceError: d is not defined(…)
all()
如果有多个异步操作同时执行,而我们想在它们都执行完成后再进行操作应该怎么办?Promise提供了all()方法
Promise.all(array)
array是Promise实例对象数组
eg:
function runasync(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('完成'); resolve('回调结果'); }, 2000); }); return p; }; function runasync1(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('完成'); resolve('回调结果1'); }, 2000); }); return p; }; function runasync2(){ var p = new Promise(function(resolve, reject){ //异步操作 setTimeout(function(){ console.log('完成'); resolve('回调结果2'); }, 2000); }); return p; }; Promise.all([runasync(), runasync1(), runasync2()]).then(function(datas){ console.log(datas); }, function(errs){ console.log(errs); })
输出: