then
返回的Promise
捕获异常,但是如果是同一个链条下的Promise
的错误会向下传递直到有catch
方法捕获,而then
方法传递两个回调函数的捕获异常的方式只会捕获谁上一个Promise
的错误
ajax('/json1.json').then(ret => {console.log(ret)}).then(undefined, err => {console.log(err)}).then(ret => {console.log(ret)}).then(ret => {console.log(ret)})// catch 捕获异常ajax('/json1.json').then(ret => {console.log(ret)}).catch(err => {// 这里能捕获之前的所有Promise的异常})// 传递then 第二个参数捕获异常ajax('/json1.json').then(ret => {console.log(ret)}).then(undefined, err => {console.log(err)throw new Error('故意的异常')}, (err) => {// 这里能捕获故意的错误}).then(ret => {console.log(ret)}).then(ret => {console.log(ret)}).catch(err => {// 这个时候已经捕获不到异常了 , 因为上一个故意的异常已经被捕获了 , 根据then方法会返回一个Promise所以捕获异常之后会返回一个成功的Promise})
还可以全局捕获异常,这种全局方式捕获异常是不推荐使用的,应该在代码块中明确的去捕获对应的异常
// 浏览器环境中window.addEventListener('unhandledrejection', event => {console.log(event.reason, event.promise)// reason 失败原因,// promise 失败的Promiseevent.preventDefault()}, false)// nodejs中process.on('unhandledRejection', (reason, promise) => {console.log(reason, promise)// reason 失败原因,// promise 失败的Promise})
如果需要无论成功和错误都需要执行则可以用finally
来实现
ajax('/json1.json').then(ret => {console.log('成功执行这个')}).catch(err => {console.log("失败执行这个")}).finally(function() {console.log("成功和失败都会执行这个")});
Promise 静态方法Promise.resolve快速的一个值转化为一个Promise
对象, 这种方式和 new Promise
返回一个值是等价的
Promise.resolve({data: "hahah"})new Promise((resolve) => {resolve({data: "hahah"})})
如果传入的是一个Promise
对象会原封不动的把这个对象返回
function ajax (url) {return new Promise((resove, reject) => {var xhr = new XMLHttpRequest()xhr.open('GET', url)// 新方法可以直接接受一个j对象xhr.responseType = 'json'xhr.onload = function () {if (this.status === 200) {resove(this.response)} else {reject(new Error(this.statusText))}}xhr.send()})}let promise1 = ajax('/url')let promise2 = Promise.resolve(promise1)console.log(promise1 === promise2) // true
如果传入的是一个对象 , 并且这个对象也有一个跟Promise
一样的then
方法,也就是说这个方也也可以接收到onFulfilled, onRejected
两个回调,并且可以调用回调传递参数,这种有then
方法的对象实现了一个thenable
的接口,支持这种对象的原因是因为原生Promise
还没有被普及之前 , 很多时候都是第三方的库实现的Promise
Promise.resolve({then (onFulfilled, onRejected) {onFulfilled('123')}}).then(ret => {console.log(ret) // 123})
Promise.reject快速创建一个一定是失败的Promise
对象,这个方法的参数就是Promise
失败的原因
Promise.reject("嘿嘿,这就是错误的理由").catch(err => {console.log(err) // 嘿嘿,这就是错误的理由})
Promise.all接收一个数组,这些元素都是一个Promise
对象,这个方法会返回一个全新的Promise
对象,当内部所有Promise
的都完成之后Promise.all
返回的Promise
对象才会完成 。这个时候Promise.all
返回的Promise
对象拿到的结果是一个数组,这个数组中包含了每一个Promise
返回的结果 。值得注意的是只有数组中的所有Promise
都成功了结束了,Promise.all
返回的Promise
对象才会成功结束 。如果数组中有一个Promise
失败的结束了,那么Promise.all
返回的Promise
对象也会以失败的结束
Promise.all([ajax('/url1'),ajax('/url2'),ajax('/url3'),ajax('/url4'),]).then(values => {console.log(values)}).catch(err => {console.log(err)})
Promise.race与 Promise.all
方法一样也是接收一个数组,这些元素都是一个Promise
对象,这个方法会返回一个全新的Promise
对象,但是与Promise.all
方法不同的是Promise.all
是等待所有任务的结束而结束,Promise.race
只会等待第一个结束的任务而结束
const request = ajax('/api/???')const timeout = new Promise((resolve, reject) => {setTimeout(() =>reject('timeout'), 5000);})Promise.race([request,timeout]).then(ret => {console.log(ret)}).catch(err => {console.log(err)})
推荐阅读
- 原神3.0乱纹精致宝箱怎么开启
- 原神伞盖菌褶的漏洞怎么玩
- 原神溢神的论证无止境的开题报告怎么通关
- 华为Nova9Pro防水吗_华为Nova9Pro防不防水
- 为什么我的世界没法做枪(我的世界里怎样能有枪)
- 我的世界手机版用命令怎么做枪(我的世界科技枪模组手机版)
- 我的世界始源之枪怎么做(我的世界怎么合成圣龙枪)
- 手机版我的世界创造模式怎么做枪(我的世界创造模式怎么进入末地)
- 我的世界暗物质武器怎么做(我的世界暗物质套怎么合成)
- 我的世界怎么造个最好的枪(我的世界怎么获得最好的精英枪)