而能够以链式连续多次执行 then 方法的原因就在于我们调用 then 方法的时候,该方法会返回一个新的 promise 对象,同样的,对于 catch 方法而言道理也是相同的,只是 catch 不能做到多次调用。
通过这个简单的实例,我们可知一个promise实例对象的执行是同步的,但是根据状态改变的句柄方法是异步执行的,同时这些句柄方法还会再次返回一个新的 Promise对象,用于进行链式调用。
Promsie实例对象中的 then或者是 catch 方法不仅可以接受 exector 中通过 resolve(value) 或者是 reject(value) 传递而来的值,还可以在其回调函数中通过 return 语句将值传递给调用链的下一个 then 或者是 catch 方法。
Promise.resolve(1).then(function(v){return v+1}).then(function(v){return v+1}).then(function(v){console.log(v)}) // 3实际上当 then 方法执行完成后,会返回一个新的 Promise 对象,并且将自己接收的值附加到这个promise对象上作为一个参数值,供调用链上的下一个 then或者是catch方法读取并处理。
如果去详细的讨论 resolve(value) 或者是 reject(value)值的传输的话,它主要有以下几种情况:
resolve(promsieObj) : 如果接收的是一个promise对象作为参数,则返回的promise对象便是这个作为参数的promsie对象。
resolve(like-promise):如果接收的参数是一个类promise对象,则将其转换并返回(带有then)一个新的promsie对象。
resolve(value):如果参数只是一个普通的js数据类型值,则返回一个新的promise对象,并且该promise对象的值就是这个参数。
Promise.resolve(Promise.resolve(3)).then(function(v){console.log(v)}); Promise.resolve('123').then(function(v){console.log(v)})resolve 与 reject 基本相同,不同的只是,如果reject接收到的是另一个promise作为参数,则返回的并不是新的promise对象,依然是其本身。
链式调用&&状态处理与ES3中我们会用 try..catch..finally 来进行异常的处理,那么在Promise中,异常都会有何种的流程呢?
Promise.reject(1).then(function(v) { console.log('success:' + v); return v }).catch(function(v) { console.log('error:' + v); return v }).then(function(v) { console.log(v); return v; }).then(function(v) { console.log(v) }); /* * error:1 * 1 * 1 * /从运算的结果上我们可以看出,then..catch..then 的结构就类似于ES3中的 try...catch..finally;
再看下面的示例,
Promise.reject(1).then(function(v) { console.log('success:' + v); return v }).catch(function(v) { console.log('error:' + v); return v }).then(function(v) { console.log(v); return v; }).catch(function(v) { console.log('error2:'+v); return v; }).then(function(v){ console.log(v) }); /* * error:1 * 1 * 1 * /从这个实例中我们就可以得知多个catch只会有一个会被触发,并且是最早的那个。
Promise.allPromise.all 可以执行一个由众多 promise对象组成的数组,并返回一个新的 promise对象,新返回的 promise对象其状态会根据所执行的 promise对象数组的状态而定,如果数组中的所有promise对象都是resolved状态,Promise.all返回的 promise对象才会触发 resolved状态,否则停止 Promise.all 的执行,并返回一个rejected 状态的promsie对象。
var p1 = Promise.resolve(1); var p2 = Promise.resolve(2); var p3 = Promise.resolve(3); Promise.all([ p1, p2, p3 ]).then(function(vs){ console.log(vs) })Promise.all 这种以执行最慢的那个异步为准的特性,可以使用它来做网页资源的预加载。
Promise.race与 Promise.all 相同,race也可以执行众多promise对象组成的数组,只是不同的是,只要在这个数组有一个Promise状态发生了改变,(resolved或者是rejected)就会使race返回一个新的 promise对象,而且这个对象的状态也是基于 promise数组执行时的状态。
var p1 = Promise.resolve(1); var p2 = Promise.resolve(2); var p3 = Promise.resolve(3); Promise.race([ p1, p2, p3 ]).then(function(vs){ console.log(vs) })如果说 Promise.all 会以Promise数组中最慢的为准,那么 race 则会以数组中最先执行的那个Promise对象为基准,因此利用这一个特性,可以用 race来设置超时时间。
var p1 = new Promise(function(resolve, reject) { setTimeout(function() { reject('超时') }, 5000) setTimeout(function() { resolve('success') }, 10000) }); var p2 = new Promise(function(resolve, reject) { setTimeout(function() { resolve('success') }, 6000) }); var p3 = new Promise(function(resolve, reject) { setTimeout(function() { resolve('success') }, 6000) }); Promise.race([p1, p2, p3]); Promise的同步调用Promise 本身是一个异步对象,当异步对象状态更改时触发对应状态的handle方法。因此如果想让多个promise对象同步执行,必须将具有依赖关系的 promise对象放置到对应的另一个promise对象的回调中。
function getAsync(v){ return new Promise(function(resolve,reject){ resolve(v); }); } function main(){ return getAsync(1000).then(pushValue).then(function(){return getAsync(500).then(pushValue)}).then(function(){return getAsync(1500).then(pushValue)}) } main().then(function(){ console.log('全部执行完成!'); }) Promise && callback