我们知道,在promise对象的then方法可以处理onfulfilled和onrejected两个事件监听回调,但是我们一般采用catch来处理onrejected的监听回调,因为catch可以捕获部分程序异常;有利于程序的健壮性。例如:
- function getBanner() {
- let p = new Promise((resolve, reject) => {
- $.ajax({
- type: "GET",
- url: "http://localhost:3000/api/index/banner",
- success: function (response) {
- resolve(response);
- },
- error: function (err) {
- reject(err);
- }
- });
- });
- return p;
- }
- let p = getBanner()
- .then(rst => {
- return rst;
- })
- .catch(err => {
- console.log(err);
- });
我们通过jQuery的ajax来向服务器发起轮播图数据的请求,上面代码若是正确的执行则会进入then方法里处理,若是异常的,也就是说必然进入catch环节,这代码看起来并没有什么,好像也并不复杂。
但是,如果在异步请求过程中出现了几个请求直接有依赖关系,则使用这种解决方案就复杂得多了。例如:
- $.ajax({
- url: "http://www.ujiuye.tech/:3000/api/firstCategory", // 所有一级分类
- dataType: "json",
- success(res) {
- $.ajax({
- url: `http://www.ujiuye.tech/:3000/api/secondCategory`, // 传递一级ID换取下属的二级分类列表
- data: {
- firstId: res['list'][0][0]['firstId']
- },
- dataType: "json",
- success(res2) {
- $.ajax({
- url: `http://www.ujiuye.tech/:3000/api/thiredCategory`, // 传递二级分类ID, 获取下属的三级分类列表
- data: {
- secondId: res2['list'][0]['secondId']
- },
- dataType: "json",
- success(res3) {
- $.ajax({
- url: `http://www.ujiuye.tech/:3000/api/categoryList`,// 传递三级分类ID, 获取下属的商品数据列表
- data: {
- thiredId: res3['list'][0]['thiredId']
- },
- dataType: "json",
- success(result) {
- console.log(result);
- }
- })
- }
- })
- }
- })
- }
- })
在小U商城项目中的商品列表页面,我们同时要发起四个请求来分别获取:一级分类、二级分类、三级分类和商品,那么这是时候利用回调函数会出现”回调地狱”的现象,即使是使用promise来优化,也会出现大量的代码嵌套,这样的代码会容易让人疑惑,而且也不利于后续的开发维护。所以我们可以使用async...await来优化这些。
例如上面请求轮播图的例子,使用async和await来优化之后:
- function getBanner() {
- let p = new Promise((resolve, reject) => {
- $.ajax({
- type: "GET",
- url: "http://localhost:3000/api/index/banner",
- success: function (response) {
- resolve(response);
- },
- error: function (err) {
- reject(err);
- }
- });
- });
- return p;
- }
- async function getData(){
- let data=await getBanner();
- console.log(data);
- }
这样的代码相比于上面的代码要简化很多,但是也有弊端,由于await只能接收promise的成功结果,也就是说,若上面代码出现了异常,则代码会中断执行。作为一个优秀的开发人员肯定不希望代码崩掉,那么该如何解决异常呢,有两种方案:一是采用try..catch来捕获异常,另外是使用catch
- async function getData() {
- try {
- let data = await getBanner();
- console.log(data);
- } catch (e) {
- console.log(e);
- }
- }
- //或者
- async function getData() {
- let data = await getBanner().catch(e => {
- console.log(e);
- })
- console.log(data);
- }
但这两种方案都又会出现嵌套,特别是若发起一些负责的请求(例如上面回调地狱的情况),则代码依然非常复杂,那么有没有更好的解决方案呢。答案是有。在项目开发过程中,我们经常使用await-to-js的技术来解决这个问题:
- function to(p) {
- return p
- .then(data => [null, data])
- .catch(err => [err, null]);
- }
其实这个方案依然是利用promise的链式调用原理来解决的。那么使用,最后代码为:
- function to(p) {
- return p
- .then(data => [null, data])
- .catch(err => [err, null]);
- }
- async function getData() {
- let [err, data] = await to(getBanner())
- }
利用这个方案,大家发现,代码量不仅大大的减少,而且兼容性更加友好。
更多内容
>>本文地址:https://www.ujiuye.com/zhuanye/2021/70198.html
声明:本站稿件版权均属中公教育优就业所有,未经许可不得擅自转载。
1 您的年龄
2 您的学历
3 您更想做哪个方向的工作?