V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
rioshikelong121
V2EX  ›  JavaScript

请教 js 中如何优雅的处理异步异常?

  •  
  •   rioshikelong121 · 2020-01-20 16:28:16 +08:00 · 3143 次点击
    这是一个创建于 1804 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
     setTimeout(() => {
        throw new Error("Whoops!");
      }, 1000);
    
    

    比如上述场景, 外层的 try-catch 等方式肯定是无法处理的,不考虑 window.onerror.

    除了使用使用 Promise.reject 改写上述代码为

    
     new Promise((resolve, reject) => {
       setTimeout(() => {
        reject("Whoops!");
      }, 1000);
     }).catch(/* errorHandle */)
    
    

    或者在 setTimout 内部 try-catch 以外,还有什么方案么?

    17 条回复    2020-01-21 10:26:15 +08:00
    H15018327040
        1
    H15018327040  
       2020-01-20 16:30:34 +08:00
    async/await?
    maichael
        2
    maichael  
       2020-01-20 16:32:38 +08:00
    setTimeout(() => {
    try {
    throw new Error("Whoops!");
    } catch {
    // handle error
    }
    }, 1000);

    这样?
    Vegetable
        3
    Vegetable  
       2020-01-20 16:32:53 +08:00
    async/await+trycatch
    Vegetable
        4
    Vegetable  
       2020-01-20 16:33:20 +08:00
    哦还有 promiss
    Vegetable
        5
    Vegetable  
       2020-01-20 16:33:31 +08:00
    e..
    fool079
        6
    fool079  
       2020-01-20 16:33:40 +08:00
    async + try catch
    zhw2590582
        7
    zhw2590582  
       2020-01-20 16:38:36 +08:00
    还有个不优雅写法
    window.addEventListener('unhandledrejection', function(err) {});
    rioshikelong121
        8
    rioshikelong121  
    OP
       2020-01-20 16:40:52 +08:00
    @zhw2590582 根据我的理解, 这个写法还得用 Promise 包装一下, 普通的 setTimeout 内抛出的异常是触发不了的。浏览器环境得用 onerror, node 环境得用 process.on('uncaughtException')
    rioshikelong121
        9
    rioshikelong121  
    OP
       2020-01-20 16:41:22 +08:00
    @Vegetable 恩 貌似引入 async/await 是个方法。
    zaul
        10
    zaul  
       2020-01-20 17:19:43 +08:00
    promise 深入了解下
    rioshikelong121
        11
    rioshikelong121  
    OP
       2020-01-20 17:34:48 +08:00
    这么多人不看描述的 :)
    SorcererXW
        12
    SorcererXW  
       2020-01-20 18:20:09 +08:00
    async function sleep(timeout){
    return new Promise(resolve=>setTImeout(timeout, resolve))
    }

    new Promise((resolve,reject)=>{
    await sleep(1000)
    try{
    throw new Error(xxxx)
    }catch(e){
    reject(e)
    }
    })
    .then()
    .catch()
    SorcererXW
        13
    SorcererXW  
       2020-01-20 18:21:13 +08:00
    在一个 promise 里面直接同步等完这 1 秒,再让 reject 处理掉抛出的 error
    liuzhaowei55
        14
    liuzhaowei55  
       2020-01-20 18:39:51 +08:00 via Android
    如果不是异常→返回这种开发模式,就尽量把逻辑完善了,测试做到位,剩下的异常异常不优雅也无所谓
    autoxbc
        15
    autoxbc  
       2020-01-20 18:55:51 +08:00
    js 的异常捕获包括 try catch 和 promise.catch 都是纯正的同步异常捕获,js 里没有真正意义上的异步异常捕获

    我猜语言设计者想保证流程控制的简单性和可预测性,换句话说,在异步流程的同步部分捕获异常更优雅
    redbuck
        16
    redbuck  
       2020-01-20 21:18:35 +08:00 via Android
    好玩一点的玩法可以写个 babel 插件,自动插入错误处理逻辑
    KuroNekoFan
        17
    KuroNekoFan  
       2020-01-21 10:26:15 +08:00
    就用 promise catch 吧
    我始终认为 promise 比 async/await 的语法在控制粒度上更细
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2566 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 10:40 · PVG 18:40 · LAX 02:40 · JFK 05:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.