JavaScript异步之拆解 Promise/A+ 规范 01

概要

Axios工具中的错误处理

整体架构流程

axios拦截器

import axios from 'axios'
const service = axios.create({})

service.interceptors.response.use(
  // 业务处理逻辑
  res => {
      const code = res.data.code;
      else if (code !== 200) {
        return Promise.reject('error')
      }
      else{ return res.data}
  },
  error => {
    return Promise.reject(error)
  }
)

业务弹窗处理

function handleSendFace(row){
    this.$confirm('是否确认"' + row.name + '"下发数据?', "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
    }).then(function() {
        return initializeOne({ deviceName: row.name });
    }).then(() => {
        this.msgSuccess("下发数据成功");
    }).catch((err)=>{
        if(err === 'cancel' || err === 'close'){
          this.msgInfo('已取消操作');
        }else if(err === 'error'){
          this.msgError('系统接口异常');  // 业务错误
        }else{
          this.msgError(err.message || err.msg || '下发数据网络失败'); // 网络错误
        }
     });
}

技术名词解释

Axios

   
     // axios 内部实际类似于:
     var chain = [dispatchRequest, undefined];  // 请求函数 + 占位
     
     // 请求拦截器插到前面
     requestInterceptors.forEach(interceptor => {
       chain.unshift(interceptor.fulfilled, interceptor.rejected);
     });
     
     // 响应拦截器插到后面
     responseInterceptors.forEach(interceptor => {
       chain.push(interceptor.fulfilled, interceptor.rejected);
     });
     
     // 然后通过 Promise 链串起来
     var promise = Promise.resolve(config);
     while (chain.length) {
       promise = promise.then(chain.shift(), chain.shift());
     }
     return promise;  // 最终返回整个 Promise 链

[[Resolve]](promise,x) 解析

// axios onFulfilled
function then(onFulfilled){
    const promise2 = new Promise((resolve,reject)=>{
        try{
            // Fulfilled promsie1
            const x = onFulfilled(value)
            resolvePromise(promise2,x,resolev,reject)
        }catch(err){
            reject(err)
        }
    })
    return promise2
}


// [[Resolve]]
function resolvePromise(promise2,x,resolve,reject){
    if(x !== null && (typeof x === 'object' || typeof x === 'function')){
        try{
            const then = x.then
            if(typeof then === 'function'){
                then.call(x,
                    (y) => resolvePromise(promise2, y, resolve, reject),
                    (r) => reject(r)  // ← 如果 x 是 rejected,就 reject promise2
                )
            }
        }catch(err){
            reject(err)
        }
    }else{
        resolve(x)
    }
}

return Promise.reject('error')

目的:让当前 .then 返回的 promsie2 的状态跟随 Promise.reject('error')

即 x === rejected Promise

.then(function(){
    const x = Promise.reject('error')
    return x
})

// 下一步:调用 resolvePromise(promise2,x,resolve,reject)
// x 调用 then,onRejected 回调拿到 'error',然后执行 reject(r)
// promise2 被 reject('error')

技术细节

Function.prototype.call

.call 作用:改变函数内部 this 的指向
then.call(x, onFulfilled, onRejected) 作用:调用函数,并显式指定函数内部的 this 执向 x

        等价于 x.then(onFulfilled, onRejected)

then.call(x, onFulfilled, onRejected)目的:只读取一次 then 属性

x.then 读取多次的场景

  • Proxy 代理对象:源于JavaScript 原生Proxy 的Getter拦截机制 。 obj.then 本质是一次属性访问操作,JavaScript 引擎每次都会执行一次“读取属性”的动作,如果obj是Proxy对象,则每次都会触发其内部的get拦截器。

小结

结合Promise A+规范,串联 Axios拦截器处理 -》组件.catch()的完整链路,直观理解如何捕获业务需要的错误信息return Promise.reject('error') 。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值