[Node] 逃离回调地狱
逃离Node回调地狱
Background :
在Node中,函数的返回结果大多利用回调的方式处理。如简单的判断文件是否存在并读取内容:
var fs = require('fs');
fs.exists('path/to/file', function (exists) {
if (exists) {
fs.readFile('path/to/file', function (err, data) {
if (err) {
console.log('error: ', err);
} else {
console.log(data);
}
});
}
});
这里暂不考虑
existsSync和readFileSync这类函数,因为并不是所有函数都有对应的Sync函数,回调形式是Node的主角。
如上述示例,当回调嵌套过多时,代码的可读性将会严重下降。这就是所谓的回调地狱。
Solution :
关于回调地狱,网上有很多解决方案。一般是利用promise,async或者Generator来解决回调嵌套。
本文给大家介绍一种新的解决方案:await(个人认为比之前的看到的promise或者async的方案好很多)。
await是ES7的特性,尽管Node的最新版本(6.4.0)已经支持大多数ES2015(ES6)特性,但是await并不被Node支持。
TypeScript
TypeScript是具有类型系统的JavaScript超集。 它可以编译成普通的JavaScript代码。 TypeScript支持任意浏览器,任意环境,任意系统并且是开源的。
利用TypeScript中的async/await可以很好的解决回调地狱:
import * as fs from 'fs';
async function existsAsync(filePath: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
fs.exists(filePath, (exists: boolean) => {
resolve(exists);
});
});
}
async function readFileAsync(filePath: string, encoding: string = 'utf8'): Promise<string> {
return new Promise<string>((resolve, reject) => {
fs.readFile(filePath, encoding, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
async function main(): Promise<void> {
let exists: boolean = await existsAsync('path/to/file');
if (exists) {
let fileContent: string = await readFileAsync('path/to/file').catch((reason) => {
console.log('rejected: ', reason);
});
console.log(fileContent);
}
}
main().then(() => {
console.log('problem solved');
});
Explanation :
由于ES2015尚未包含await特性,所以TypeScript中的await在编译成js之后利用的是Generator来实现await效果的。
TypeScript编译的target默认是ES5,所以想使用async/await要把
tsconfig.json中的target属性改为es2015。
Conclusion :
利用TypeScript中的async/await可以将Node中的回调扁平化,比promise式的链式调用更易读。个人认为是解决回调地狱的首选方案。
TypeScript作为js的超集,可以用在任何使用js的场景。配合typings和VS code的IntelliSense,写js再也不痛苦啦~
[Node] 逃离回调地狱的更多相关文章
- 避免Node.js中回调地狱
为了解决这个阻塞问题,JavaScript严重依赖于回调,这是在长时间运行的进程(IO,定时器等)完成后运行的函数,因此允许代码执行经过长时间运行的任务. downloadFile('example. ...
- ES6(promise)_解决回调地狱初体验
一.前言 通过这个例子对promise解决回调地狱问题有一个初步理解. 二.主要内容 1.回调地狱:如下图所示,一个回调函数里面嵌套一个回调函数,这样的代码可读性较低也比较恶心 2.下面用一个简单的例 ...
- JavaScript 中回调地狱的今生前世
1. 讲个笑话 JavaScript 是一门编程语言 2. 异步编程 JavaScript 由于某种原因是被设计为单线程的,同时由于 JavaScript 在设计之初是用于浏览器的 GUI 编程,这也 ...
- JavaScript异步编程__“回调地狱”的一些解决方案
异步编程在JavaScript中非常重要.过多的异步编程也带了回调嵌套的问题,本文会提供一些解决“回调地狱”的方法. setTimeout(function () { console.log('延时触 ...
- [译] 回调地狱——JavaScript异步编程指南
原文:Callback Hell 什么是 “回调地狱”? 在 JavaScript 中,我们经常通过回调来实现异步逻辑,一旦嵌套层级多了,代码结构就容易变得很不直观,最后看起来像这样: fs.read ...
- Promise如何解决回调地狱
为什么要有promise:解决(回调地狱)的问题 ### 回调地狱: ```js //跟以前的if条件地狱很像 // if(){ // if(){ // if(){ // } // } //} $.g ...
- Node.js回调概念
什么是回调? 回调是一个异步等效的功能.在完成特定任务回调函数被调用. Node大量使用了回调.Node的所有的API都支持回调这样的一种方式. 例如,一个函数读取一个文件可能开始读取文件,并使得下一 ...
- iOS 如何优雅的处理“回调地狱Callback hell”(一) (下)
了解完流程之后,就可以开始继续研究源码了.在PromiseKit当中,最常用的当属then,thenInBackground,catch,finally - (PMKPromise *(^)(id)) ...
- iOS 如何优雅的处理“回调地狱Callback hell”(一) (上)
前言 最近看了一些Swift关于封装异步操作过程的文章,比如RxSwift,RAC等等,因为回调地狱我自己也写过,很有感触,于是就翻出了Promise来研究学习一下.现将自己的一些收获分享一下,有错误 ...
随机推荐
- 实现目标文件与源码分开的makefile测试实验
uboot提供了两种编译策略,即可以将生成的目标文件与源码混在一起,也可以将生成的目标文件与源码分开.通过对uboot Makefile的分析,笔者编写了一个简单的实现这种功能的Makfile. 顶层 ...
- chmod 命令 set uid ,set gid,sticky bit 说明
permission的符号模式表: 模式 名字 说明 r 读 设置为可读权限 w 写 设置为可写权限 x 执行权限 设置为可执行权限 X 特殊执行权限 只有当文件为目录文件,或者其他类型的用户有可执行 ...
- 版本控制工具git入门
版本控制工具的历史 不说了,放张图 两者的区别:集中式需要一个中心服务器放置最新的文件,需要联网操作.分布式可以再不联网的情况下操作,前提要拥有版本库 git安装 略 github注册 略 如何在g ...
- [转贴]WebService的简单实现 C++
WebService的简单实现 一.socket主机创建和使用过程 1.socket()//创建套接字 2.Setsockopt()//将套接字属性设置为允许和特定地点绑定 3.Bind()//将套接 ...
- 【CF】207 Div.1 B.Xenia and Hamming
这题目一看很牛逼,其实非常easy.求求最小公倍数,最大公约数,均摊复杂度其实就是O(n). /* 356B */ #include <iostream> #include <str ...
- JSOI2008 火星人prefix
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2918 Solved: 866[Submit][ ...
- 【转】Android:Animation的简单学习--不错
原文网址:http://blog.csdn.net/huangbiao86/article/details/6683665 Animation动画效果.提供了一系列的动画效果,可以应用大多数 的控件. ...
- 微软Sharepoint的一些缺点
转:http://bbs.tianya.cn/post-144-566491-1.shtml 微软Sharepoint的一些缺点(一) 微软Sharepoint的一些缺点 关于SharePoint,它 ...
- OracleHelper[.Net 连接Oracle数据库的封装类]
using System; using System.Configuration; using System.Data; using System.Data.OracleClient; using S ...
- 基于.NET平台常用的框架和开源程序整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中 也积累了一些开源的组件,就目前想到的先整理于此,如果再想到, ...