这篇文章不包括Promise的基本用法,主要是一些平时不常用的。。。。。。
then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。以下例子最终会先输出catch error,然后再抛出错误信息:
const testPromise = new Promise(function (resolve, reject) { let a = 5 if (a === 5) { resolve('success') } else { reject('catch error') } }) testPromise.then(res => { throw new Error('then error') }).catch(err => { console.log('catch error') console.log(err) })
Promise本身是一个构造函数
typeof Promise // 'function'
Promise
有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。
当Promise报错时会走then里边的第二个回调函数,then里边没有第二个回调函数时,会走catch里的回调函数。
因为then和 catch方法返回promise 对象, 所以它们可以被链式调用。
注意: 如果一个promise对象处在fulfilled或rejected状态而不是pending状态,那么它也可以被称为settled状态。你可能也会听到一个术语resolved ,它表示promise对象处于settled状态。
方法:
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。下面的的例子中fn1, fn2, fn3三个函数并列执行,当这三个函数都执行完时到then里,有异常到catch里。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then, 就是下边result
Promise.all([fn1, fn2, fn3]).then([fn1res, fn2res, fn3res] => {}).catch(...);
Promise.all有个缺点:
如果Promise.all参数中的promise有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise
的结果。其他回调成功(resolve)的也不会返回。
all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调,不管结果本身是成功状态还是失败状态」,这就是race方法,这个词本来就是赛跑的意思。有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。
如果最快的那个返回的是失败的话,其他的成功的也不会在执行了。
race的用法与all一样:
function runAsync1(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('异步任务1执行完成'); resolve('随便什么数据1'); }, 1000); }); return p; } function runAsync2(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('异步任务2执行完成'); resolve('随便什么数据2'); }, 2000); }); return p; } function runAsync3(){ var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.log('异步任务3执行完成'); resolve('随便什么数据3'); }, 2000); }); return p; } Promise .race([runAsync1(), runAsync2(), runAsync3()]) .then(function(results){ console.log(results); });
以上代码中没有输出‘随便什么数据2’和‘随便什么数据3’,promise的因为状态只能改变一次,但runAsync2和runAsync3里边的代码被执行了。
在race参数里谁最先执行完,就把谁的返回结果传给then里的回调函数的参数。但是在then里面的回调开始执行时,runAsync2()和runAsync3()并没有停止,仍旧再执行。于是再过1秒后输出了他们结束的标志。
这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:
//请求某个图片资源 function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } img.src = 'xxxxxx'; }); return p; } //延时函数,用于给请求计时 function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('图片请求超时'); }, 5000); }); return p; } Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); });
requestImg函数会异步请求一张图片,我把地址写为"xxxxxx",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,控制台报出“图片请求超时”的信息。
原文: