正文
3. …….
4.第4次调用next()方法的时候,由于循环已经结束了,所以函数调用立即返回,done属性表明 Generator 函数已经结束运行,value是undefined的,因为这次调用并没有执行任何语句
“The Promise object is used for asynchronous computations. A Promise represents an operation that hasn’t completed yet, but is expected in the future. —https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。
一个 Promise 一般有3种状态:
1.pending:初始状态, 不是fulfilled,也不是rejected
2.fulfilled:操作成功完成
3.rejected:操作失败
一个 Promise 的生命周期如下图:
下面我们看一段具体代码:
asyncFunction 这个函数会返回 Promise 对象, 对于这个 Promise 对象,我们调用它的then 方法来设置resolve后的回调函数,catch方法来设置发生错误时的回调函数。
该 Promise 对象会在setTimeout之后的16ms时被resolve, 这时then的回调函数会被调用,并输出 ‘Async Hello world’ 。
在这种情况下catch的回调函数并不会被执行(因为 Promise 返回了resolve), 不过如果运行环境没有提供 setTimeout 函数的话,那么上面代码在执行中就会产生异常,在 catch 中设置的回调函数就会被执行。
小结
如果是编
写一个 SDK 或 API,推荐使用传统的 Callback 或者 Promise,不使用 Generator 的原因是:
由此看来学习 Promise 是水到渠成的事情。
2.2 Node.js 异常处理
一个友好的错误处理机制应该满足三个条件:
1.对于引发异常的用户,返回 500 页面
2.其他用户不受影响,可以正常访问
3.不影响整个进程的正常运行
下面我们就以这三个条件为原则,具体介绍下 Express、Koa 中的异常处理:
在 Express 中有一个内置的错误处理中间件,这个中间件会处理任何遇到的错误。如果你在 Express 中传递了一个错误给next(),而没有自己定义的错误处理函数处理这个错误,这个错误就会被 Express 默认的错误处理函数捕获并处理,而且会把错误的堆栈信息返回到客户端,这样的错误处理是非常不友好的,还好我们可以通过设置NODE_ENV环境变量为production,这样 Express 就会在生产环境模式下运行应用,生产环境模式下 Express 不会把错误的堆栈信息返回到客户端。
在 Express 项目中可以定义一个错误处理的中间件用来替换 Express 默认的错误处理函数:
在所有其他app.use()以及路由之后引入以上代码,可以满足以上三个友好错误处理条件,是一种非常友好的错误处理机制。
我们以Koa 1.x为例,看代码:
把上面的代码放在所有app.use()函数前面,这样基本上所有的同步错误均会被 try{} catch(err){} 捕获到了,具体原理大家可以了解下 Koa 中间件的机制。
上面的两种异常处理方法,只能捕获同步错误,而异步代码产生的错误才是致命的,uncaughtException错误会导致当前的所有用户连接都被中断,甚至不能返回一个正常的HTTP 错误码,用户只能等到浏览器超时才能看到一个no data received错误。