使用promise报错_为什么 es6-promise不抛出错误

本文探讨了在使用es6-promise时,如何处理和捕获内部错误。当代码触发错误,如尝试修改只读变量,错误会被存储并由Promise的reject方法处理。由于错误未在控制台显示,需要通过调试源码发现。解决方案是在最后添加额外的then或catch块来捕获错误。通过这种方式,可以确保所有可能出现的错误都能得到适当的处理。
摘要由CSDN通过智能技术生成

如果你的项目使用的是 es6-promise 运行下面代码,是不会抛出错误的。

const p1 = new Promise((resolve) => {
    resolve(1)
}).then(data => {
    console.log("first then")
}).then(data => {
    console.log("second then start")
    const d = 0;
    d = 9;
    console.log("second then end")
})

运行结果

21e3adf86b7e467dc81de1da109f4d97.png

上述代码运行到这里的时候,是会报一个 Error: "d" is read-only 错误的,但是这个错误不会现实中 console 控制台中。

    const d = 0;
    d = 9;

因此,我只能debug 一下源码,当运行到 ,其实就是在调用 invokeCallback 方法 (已经删除部分无关代码)

    const d = 0;
    d = 9;

invokeCallback

function tryCatch(callback, detail) {
  try {
    return callback(detail);
  } catch(e) {
    TRY_CATCH_ERROR.error = e;
    return TRY_CATCH_ERROR;
  }
}

function invokeCallback(settled, promise, callback, detail) {
  let hasCallback = isFunction(callback),
      value, error, succeeded, failed;

  if (hasCallback) {

   // ①执行callback ,触发 "d" is read-only 错误,然后把错误存储在  TRY_CATCH_ERROR.error 里面
    value = tryCatch(callback, detail);
    if (value === TRY_CATCH_ERROR) {
      failed = true;
      error = value.error;
      value.error = null;
    } else {
      succeeded = true;
    }
  } else {

  }

  if (promise._state !== PENDING) {
    // noop
  } else if (hasCallback && succeeded) {
    resolve(promise, value);
  } else if (failed) {
   //②执行 reject 方法,error 就是 TRY_CATCH_ERROR.error 存储的 "d" is read-only 错误
    reject(promise, error);
  } else if (settled === FULFILLED) {
    fulfill(promise, value);
  } else if (settled === REJECTED) {
    reject(promise, value);
  }
}

执行 invokeCallback 方法,发生了两件事情。

①执行callback ,触发 "d" is read-only 错误,然后把错误存储在 TRY_CATCH_ERROR.error 里面

② 执行 reject 方法,error 就是 TRY_CATCH_ERROR.error 存储的 "d" is read-only 错误

resolve

function reject(promise, reason) {
  if (promise._state !== PENDING) { return; }
 //  改变当前promise 的状态
  promise._state = REJECTED;
//  把当前 promise 的值设置为 "d" is read-only 的 error
  promise._result = reason;

  asap(publishRejection, promise);
}

publishRejection

function publishRejection(promise) {
  if (promise._onerror) {
    promise._onerror(promise._result);
  }
  // 执行 publish
  publish(promise);
}

publish

function publish(promise) {
  let subscribers = promise._subscribers;
  let settled = promise._state;

  // ③ subscribers 为空,直接返回
  if (subscribers.length === 0) { return; }

  let child, callback, detail = promise._result;

  for (let i = 0; i < subscribers.length; i += 3) {
    child = subscribers[i];
    callback = subscribers[i + settled];

    if (child) {
      invokeCallback(settled, child, callback, detail);
    } else {
      callback(detail);
    }
  }

  promise._subscribers.length = 0;
}

publish 就是执行 subscribers 里面的promise,但是由于此例子中,报错的then 后面已经没有then了,subscribers 为空,所以运行到③ , publish 直接返回。

所以解决方法也很简单,就是,在后面再加一个 then , 或catch

const p1 = new Promise((resolve) => {
    resolve(1)
}).then(data => {
    console.log("first then")
}).then(data => {
    console.log("second then start")
    const d = 0;
    d = 9;
    console.log("second then end")
}).then(() => { }, (e) => {
    console.log(e)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值