SlideShare a Scribd company logo
NODE.JS 异步任务的四种模式
PRESENTED BY 贾赛奇
异步任务的四种模式
• 回调函数
• PROMISE
• CO 的黑魔法
• ASYNC / AWAIT
BEFORE…
回顾一下 NODE.JS 的线程模型
NODE.JS 单线程模型
NODE.JS 只有一个线程
NODE.JS 单线程模型
NODE.JS 只有一个线程
NODE.JS 单线程模型
异步模式之一:回调函数
const fs = require('fs')
fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err
console.log(data)
})
异步模式之一:回调函数
错误处理:
• 基于人工约定
• 通常约定 callback 第一个参数表示错误
• callback 中抛出的异常将无法捕获(上例的 throw err 将导致进程崩溃)
异步模式之二:PROMISE
• 早期实现:JQUERY.DEFERRED
• 标准:PROMISE/A+
• 原生 PROMISE、BLUEBIRD、Q、JQUERY 3.0 都实现了 PROMISE/A+
异步模式之二:PROMISE
const fs = require('fs')
require('bluebird').promisifyAll(fs)
fs.readFileAsync('/etc/passwd').then(data => {
console.log(data)
}).catch(err => {
throw err
})
异步模式之二:PROMISE
// 链式调用
const fs = require('fs')
require('bluebird').promisifyAll(fs)
fs.readFileAsync('/etc/passwd').then(data => {
return data
}).catch(err => {
throw err
}).then(data => {
console.log(data)
}).catch(err => {
console.error(err)
})
异步模式之二:PROMISE
链式调用:
• .THEN(…) 和 .CATCH(…) 会返回一个新的 PROMISE,其结果由 ONFULFILLED HANDLER 和
ONREJECTED HANDLER 决定
错误处理:
• 通过 .THEN(…) 第二个参数或 .CATCH(…) 来注册 ONREJECTED HANDLER
• 在 .THEN(…) 和 .CATCH(…) 抛出的异常不会导致进程崩溃,而会传递到其返回的
PROMISE 中
异步模式之三:CO
• YIELD 和 GENERATOR 提供了使函数暂停的能力
• CO 充分利用了这种特性,在 YIELD PROMISE 时使函数暂停,在 PROMISE 完成后继续执
行函数
• CO 消除掉了回调函数,使异步调用过程看起来像调用同步方法
异步模式之三:CO
co(function * () {
const result = yield Promise.resolve('foobar')
return result // 'foobar'
})
异步模式之三:CO
错误处理:
• 可以使用 TRY … CATCH … FINALLY 关键字环绕含有 YIELD 的代码块
• CO(…) 本身返回一个 PROMISE,当第一个参数的生成器函数内部有未捕获异常时,该
PROMISE 将被 REJECTED
异步模式之四:ASYNC / AWAIT
• 与 CO 对 YIELD / GENERATOR 的充分利用无本质区别
• BABEL 对 ASYNC / AWAIT 的转译实际上就是转换成了 YIELD / GENERATOR
• 可以与 CO 对等替换,Co(function * () {}) 替换为 async function () {},
yield <promise> 替换为 await <promise>
• 语义上相比 CO 更加符合直觉
• CO 可以直接 YIELD 数组,而 AWAIT 需要使用 AWAIT PROMISE.ALL([…])
异步模式之四:ASYNC / AWAIT
// async 函数自动返回 Promise,等价于 co(function * { ... })
async function fetchFoobarAsync () {
const result = await Promise.resolve('foobar')
return result // 'foobar'
}
异步模式之四:ASYNC / AWAIT
错误处理:与 CO 完全一致
最佳实践
• ASYNC / AWAIT 拥有最佳的可读性和可调试性、更友好的错误提示,以及支持使用
JSDOC 进行标注
• NODE 7.6.0 正式原生支持了 ASYNC / AWAIT 关键字
• 最佳实践:使用 BLUEBIRD 将所有异步操作 PROMISIFY,使用 ASYNC / AWAIT 进行异步调
用
• 最佳实践:将所有异步方法以 ASYNC 后缀命名

More Related Content

PDF
不一樣的Web server... coServ
PDF
給 GLib 使用者的 libev 簡介
PDF
Node develop expirements
PPTX
從 Singleton 談 constructor
PPTX
C++11综述/新特性描述/Overview of C++11 New Features
PDF
Javascript primer plus
PPTX
Javascript异步编程模型的演变
PDF
並行與平行
不一樣的Web server... coServ
給 GLib 使用者的 libev 簡介
Node develop expirements
從 Singleton 談 constructor
C++11综述/新特性描述/Overview of C++11 New Features
Javascript primer plus
Javascript异步编程模型的演变
並行與平行

What's hot (14)

PDF
Sidekiq 源码分析
PPTX
Excel vba實務應用 第3天
PDF
Jdbc中操作Blob、Clob等对象
PPT
Node分享 展烨
PPTX
NSCopying between Objective-C and Swift
PDF
S1: InnoDB AIO原理及相关bug分析
DOC
volatile的作用
PDF
Ruby 使用手冊 (Part 1)
PDF
Brainfuck interpreter 分析新竹碼農0307
PDF
Ruby的类和对象模型
PDF
流程語法與函式
PDF
SQL injection duplicate error principle
PDF
Ceph中国社区9.19 Ceph IO 路径 和性能分析-王豪迈05
PDF
Tcfsh bootcamp day2
Sidekiq 源码分析
Excel vba實務應用 第3天
Jdbc中操作Blob、Clob等对象
Node分享 展烨
NSCopying between Objective-C and Swift
S1: InnoDB AIO原理及相关bug分析
volatile的作用
Ruby 使用手冊 (Part 1)
Brainfuck interpreter 分析新竹碼農0307
Ruby的类和对象模型
流程語法與函式
SQL injection duplicate error principle
Ceph中国社区9.19 Ceph IO 路径 和性能分析-王豪迈05
Tcfsh bootcamp day2
Ad

Node.js 异步任务的四种模式