栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Node.js最佳实践异常处理

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Node.js最佳实践异常处理

更新:Joyent现在有自己的指南。以下信息更多是摘要:

安全地“抛出”错误

理想情况下,我们希望尽可能避免未捕获的错误,因此,除了从字面上抛出错误外,我们还可以根据我们的代码体系结构使用以下方法之一安全地“抛出”错误:

  • 对于同步代码,如果发生错误,请返回错误:
        // Define divider as a syncrhonous function    var divideSync = function(x,y) {        // if error condition?        if ( y === 0 ) { // "throw" the error safely by returning it return new Error("Can't divide by zero")        }        else { // no error occured, continue on return x/y        }    }    // Divide 4/2    var result = divideSync(4,2)    // did an error occur?    if ( result instanceof Error ) {        // handle the error safely        console.log('4/2=err', result)    }    else {        // no error occured, continue on        console.log('4/2='+result)    }    // Divide 4/0    result = divideSync(4,0)    // did an error occur?    if ( result instanceof Error ) {        // handle the error safely        console.log('4/0=err', result)    }    else {        // no error occured, continue on        console.log('4/0='+result)    }
  • 对于基于回调的(即异步)代码,回调的第一个参数为
    err
    ,如果发生错误
    err
    则为错误,如果未发生错误
    err
    则为
    null
    。其他任何参数都遵循以下
    err
    参数:
        var divide = function(x,y,next) {        // if error condition?        if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero"))        }        else { // no error occured, continue on next(null, x/y)        }    }    divide(4,2,function(err,result){        // did an error occur?        if ( err ) { // handle the error safely console.log('4/2=err', err)        }        else { // no error occured, continue on console.log('4/2='+result)        }    })    divide(4,0,function(err,result){        // did an error occur?        if ( err ) { // handle the error safely console.log('4/0=err', err)        }        else { // no error occured, continue on console.log('4/0='+result)        }    })
  • 对于事件代码,错误可能发生在任何地方,而不是引发错误,请触发
    error
    事件:
        // Definite our Divider Event Emitter    var events = require('events')    var Divider = function(){        events.EventEmitter.call(this)    }    require('util').inherits(Divider, events.EventEmitter)    // Add the divide function    Divider.prototype.divide = function(x,y){        // if error condition?        if ( y === 0 ) { // "throw" the error safely by emitting it var err = new Error("Can't divide by zero") this.emit('error', err)        }        else { // no error occured, continue on this.emit('divided', x, y, x/y)        }        // Chain        return this;    }    // Create our divider and listen for errors    var divider = new Divider()    divider.on('error', function(err){        // handle the error safely        console.log(err)    })    divider.on('divided', function(x,y,result){        console.log(x+'/'+y+'='+result)    })    // Divide    divider.divide(4,2).divide(4,0)

安全地“捕捉”错误

但是有时,仍然有一些代码会在某个地方引发错误,如果我们不安全地捕获它,可能会导致未捕获的异常并可能导致应用程序崩溃。根据我们的代码体系结构,我们可以使用以下方法之一来捕获它:

  • 当我们知道错误发生在哪里时,可以将该部分包装在node.js域中
        var d = require('domain').create()    d.on('error', function(err){        // handle the error safely        console.log(err)    })    // catch the uncaught errors in this asynchronous or synchronous pre block    d.run(function(){        // the asynchronous or synchronous pre that we want to catch thrown errors on        var err = new Error('example')        throw err    })
  • 如果我们知道错误发生在哪里是同步代码,并且由于某种原因不能使用域(也许是旧版本的节点),则可以使用try catch语句:
        // catch the uncaught errors in this synchronous pre block    // try catch statements only work on synchronous pre    try {        // the synchronous pre that we want to catch thrown errors on        var err = new Error('example')        throw err    } catch (err) {        // handle the error safely        console.log(err)    }

但是,请注意不要

try...catch
在异步代码中使用,因为不会捕获异步引发的错误:

        try {        setTimeout(function(){ var err = new Error('example') throw err        }, 1000)    }    catch (err) {        // Example error won't be caught here... crashing our app        // hence the need for domains    }

如果确实要

try..catch
与异步代码一起使用,则在运行Node 7.4或更高版本时,可以使用
async/await
本机来编写异步函数。

要注意的另一件事

try...catch
是将完成回调包装在
try
语句中的风险,如下所示:

        var divide = function(x,y,next) {        // if error condition?        if ( y === 0 ) { // "throw" the error safely by calling the completion callback // with the first argument being the error next(new Error("Can't divide by zero"))        }        else { // no error occured, continue on next(null, x/y)        }    }    var continueElsewhere = function(err, result){ throw new Error('elsewhere has failed')    }    try { divide(4, 2, continueElsewhere) // ^ the execution of divide, and the execution of  //   continueElsewhere will be inside the try statement    }    catch (err) { console.log(err.stack) // ^ will output the "unexpected" result of: elsewhere has failed    }

随着代码变得更加复杂,此陷阱非常容易实现。因此,最好使用域或返回错误,以避免(1)异步代码中未捕获的异常(2)尝试捕获不需要的执行。在允许适当的线程而不是Javascript的异步事件机器风格的语言中,这不是问题。

  • 最后,在未包裹域或try catch语句的地方发生未捕获的错误的情况下,我们可以使用
    uncaughtException
    侦听器使应用程序不崩溃(但是这样做会使应用程序处于未知状态)):
        // catch the uncaught errors that weren't wrapped in a domain or try catch statement    // do not use this in modules, but only in applications, as otherwise we could have multiple of these bound    process.on('uncaughtException', function(err) {        // handle the error safely        console.log(err)    })    // the asynchronous or synchronous pre that emits the otherwise uncaught error    var err = new Error('example')    throw err


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/382052.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号