Promise是异步编程的一个解决方案,相比传统的解决方法——回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,也使得代码结构更为清晰,便于维护。Promise 是一个对象,从他能够获取异步操做的消息,他也是一个容器,里面包含着事件结束以后要进行的操做。javascript
Promise对象有两个特色:java
pending
(进行中)、resolved
(已完成)、rejected
(已失败),具体处于哪种状态是由异步操做的结果来决定的,其余的任何操做都没法改变这个状态。Promise是一个构造函数,生成一个实例。ajax
var promise = new Promise(function(resolve,reject){ if(/异步成功/){ resolve(val); }else{ reject(val); } }); promise.then(function(val){ /成功后执行的函数/ },function(error){ /失败后执行的函数/ });
Promise构造函数接收一个函数做为参数,这个函数有两个参数resolve、reject,这两个参数也是两个函数,有javascript引擎提供,不须要本身实现。其中,resolve函数的做用是将Promise对象的状态由"进行中"变为"已完成",在异步操做成功的时候调用,并将异步操做的结果以参数的形式传出,就是上例中的val
。reject函数的做用是将Promise对象的状态由"进行中"变为"已失败",在异步操做失败的时候调用,并将操做失败的错误已参数的形式传出。编程
Promise的实例能够调用then
方法,then
方法有两个函数做为参数,第一个函数是Promise对象状态变为resoloved时执行的函数,第二个函数是Promise对象状态变为rejected时执行的函数,第二个参数是可选的。数组
一个典型的例子:异步读取文件promise
function readFileFn(filename){ return new Promise(function(resolve,reject){ fs.readfile(filename,function(err,data){ if(err){ reject(err); }else{ resolve(data); } }); }); } readFileFn("./test.txt").then(function(data){ console.log(data.toString()); //其余操做... },function(err){ console.log(err); });
then
方法能够采用链式的写法,即:异步
promise.then(...).then(...).then(..)
异步编程
具体的例子:函数
var promise = new Promse(function(resolve,reject){ resolve(1); //将Promise对象的状态改成resolved,并传递参数1 }); promise.then(function(val){ console.log(val); // 1 return val*3; }).then(function(val){ console.log(val); //3 return val*3; }).then(function(val){ console.log(val); //9 });
then
方法里省略第二个参数,而后在链式调用的尾部使用catch
方法来捕获异步操做或者then
方法中的错误;readFileFn("./test.txt").then(function(data){ console.log(data.toString()); //其余操做... }).catch(function(err){ console.log(err); }) //另外一种用法 var promise = new Promise(function(resolve,reject){ reject(new Error("test")); }); promise.then(function(val){ //... }).catch(function(err){ console.log(err); //.. });
var p = Promise.all([a,b,c]); //a,b,c都是Promise的实例
prototype
p最终的状态由a,b,c三者决定:
1>.当a,b,c的状态都是resolved时,p的状态才是resolved,此时a,b,c的返回值组成一个数组,传给p的回调函数。
2>.只要 a,b,c中有一个状态时reject,p的状态就是reject,此时一个reject的实例的返回值会传递给p的回调函数。
var promises = [1,2,3,4].map(function(id){ return readFileFn("./test"+id+".txt"); //readFileFn()是上面声明过的函数 }); Promise.all(promises).then(function(val){ //... }).catch(function(err){ //... });
var promise = Promise.resolve($.ajax("./test.txt"));
Promise.resolve()有四种类型的参数:
1>.Promise实例,那么函数不会对参数作任何修改,原样返回;
2>.普通对象,如同上例,会转换成一个promise对象返回;
3>.非对象,即普通的变量,好比"hello"、2 等等,此时会返回一个新的Promise实例,状态为resolved(),"hello"会以参数的形式传给
then
的第一个方法;
var p = Promise.resolve("hello"); p.then(function(val){ //此函数会当即执行 console.log(val); //hello });
4>.不带参数,会直接返回一个Resolved状态的Promise对象。
done()
方法,位于回调链的最尾端,用于捕获错误。promise.then(function(){}).then(function(){}).catch(function(){}).done();
done()
的区别是能够接受一个普通的回调函数做为参数,且该函数必定会执行。