JavaScript Promise的错误处理
今天我们来学习在Promise中如何处理异常错误。
假设有一个getUserById
函数用来获取用户,它返回一个promise。
function getUserById(id) { return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
throw new Error
在返回promise之前,如果id参数不合法throw一个异常
function getUserById(id) { if (typeof id !== 'number' || id <= 0) { throw new Error('参数ID不合法'); } return new Promise((resolve, reject) => { resolve({ id: id, username: 'admin' }); }); }
接着,调用这个promise,设置then、catch回调
getUserById('a') .then(user => console.log(user.username)) .catch(error => console.log(error)); // 输出: // Uncaught Error: 参数ID不合法
可以看到,then、catch都不会走,如果要捕获这个错误,必须要用try/catch
try { getUserById('a') .then(user => console.log(user.username)) .catch(error => console.log(`.catch被调用:${error}`)); } catch (error) { console.log(`try/catch被调用:${error}`); } // 输出: // try/catch被调用:Error: 参数ID不合法
在try/catch内成功捕获错误。
在Promise内throw
在promise内抛出异常
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { throw new Error('未登录,获取用户信息失败'); } resolve({ id: id, username: 'admin' }); }); }
调用
try { getUserById(10) .then(user => console.log(user.username)) .catch(error => console.log(`.catch被调用:${error}`)); } catch (error) { console.log(`try/catch被调用:${error}`); } // 输出: // .catch被调用:Error: 未登录,获取用户信息失败
如果在promise内去throw抛出异常,则可以在.catch的回调中捕获到,在try/catch中无法捕获
如果使用链式调用promise,.catch将捕获任何一个promise的异常错误
promise1 .then(promise2) .then(promise3) .then(promise4) .catch(err => console.log(err));
在上面的例子里,如果promise1、promise2有异常都会被.catch捕获到。
使用reject()
函数
使用reject()函数和上面throw抛出异常一样,
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('未登录,获取用户信息失败'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)) .catch(error => console.log(`.catch被调用:${error}`)); } catch (error) { console.log(`try/catch被调用:${error}`); } // 输出: // .catch被调用:未登录,获取用户信息失败
在上面例子里,我们没有在promise内throw异常,而是调用reject()函数。同样也是在.catch被捕获。
没有.catch()方法会怎样
下面的例子里没有为promise提供.catch回调来捕获错误
let authorized = false; function getUserById(id) { return new Promise((resolve, reject) => { if (!authorized) { reject('未登录,获取用户信息失败'); } resolve({ id: id, username: 'admin' }); }); } try { getUserById(10) .then(user => console.log(user.username)); // 下面的代码会执行 console.log('next'); } catch (error) { console.log(`try/catch被调用:${error}`); } // 输出: // next // Uncaught (in promise) 未登录,获取用户信息失败
如果promise被resolve,则可以省略catch()回调。上面console.log('next')将会执行。
总结
在promise中,.catch()函数会捕获promise内的throw错误和reject抛出的错误。
如果promise发生异常,而没有.catch()函数,也会在控制台抛出异常,但后面的代码依旧会执行。