[Node] 逃离回调地狱

时间:2022-08-28 19:49:12

逃离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);
}
});
}
});

这里暂不考虑existsSyncreadFileSync这类函数,因为并不是所有函数都有对应的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] 逃离回调地狱的更多相关文章

  1. 避免Node&period;js中回调地狱

    为了解决这个阻塞问题,JavaScript严重依赖于回调,这是在长时间运行的进程(IO,定时器等)完成后运行的函数,因此允许代码执行经过长时间运行的任务. downloadFile('example. ...

  2. ES6&lpar;promise&rpar;&lowbar;解决回调地狱初体验

    一.前言 通过这个例子对promise解决回调地狱问题有一个初步理解. 二.主要内容 1.回调地狱:如下图所示,一个回调函数里面嵌套一个回调函数,这样的代码可读性较低也比较恶心 2.下面用一个简单的例 ...

  3. JavaScript 中回调地狱的今生前世

    1. 讲个笑话 JavaScript 是一门编程语言 2. 异步编程 JavaScript 由于某种原因是被设计为单线程的,同时由于 JavaScript 在设计之初是用于浏览器的 GUI 编程,这也 ...

  4. JavaScript异步编程&lowbar;&lowbar;&OpenCurlyDoubleQuote;回调地狱”的一些解决方案

    异步编程在JavaScript中非常重要.过多的异步编程也带了回调嵌套的问题,本文会提供一些解决“回调地狱”的方法. setTimeout(function () { console.log('延时触 ...

  5. &lbrack;译&rsqb; 回调地狱——JavaScript异步编程指南

    原文:Callback Hell 什么是 “回调地狱”? 在 JavaScript 中,我们经常通过回调来实现异步逻辑,一旦嵌套层级多了,代码结构就容易变得很不直观,最后看起来像这样: fs.read ...

  6. Promise如何解决回调地狱

    为什么要有promise:解决(回调地狱)的问题 ### 回调地狱: ```js //跟以前的if条件地狱很像 // if(){ // if(){ // if(){ // } // } //} $.g ...

  7. Node&period;js回调概念

    什么是回调? 回调是一个异步等效的功能.在完成特定任务回调函数被调用. Node大量使用了回调.Node的所有的API都支持回调这样的一种方式. 例如,一个函数读取一个文件可能开始读取文件,并使得下一 ...

  8. iOS 如何优雅的处理&OpenCurlyDoubleQuote;回调地狱Callback hell”&lpar;一&rpar; &lpar;下&rpar;

    了解完流程之后,就可以开始继续研究源码了.在PromiseKit当中,最常用的当属then,thenInBackground,catch,finally - (PMKPromise *(^)(id)) ...

  9. iOS 如何优雅的处理&OpenCurlyDoubleQuote;回调地狱Callback hell”&lpar;一&rpar; &lpar;上&rpar;

    前言 最近看了一些Swift关于封装异步操作过程的文章,比如RxSwift,RAC等等,因为回调地狱我自己也写过,很有感触,于是就翻出了Promise来研究学习一下.现将自己的一些收获分享一下,有错误 ...

随机推荐

  1. Ejabberd导入到eclipse

    ejabberd 在eclipse(erlide)中的配置.调试.运行   最近在折腾ejabberd,将ejabberd项目配置到eclipse中进行编译.调试等,现在将过程记下来,希望能帮助到需要 ...

  2. 51Nod-1091 线段的重叠

    51Nod 1091:  http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1091   1091 线段的重叠 基准时间限制: ...

  3. Bash 4&period;4 中新增的 &dollar;&lbrace;parameter&commat;operator&rcub; 语法

    Bash 4.4 中新增了一种 ${...} 语法,长这样:${parameter@operator}.根据不同的 operator,它展开后的值可能是 parameter 这个参数的值经过某种转换后 ...

  4. DataTable 的使用

    DataTable CFHMXdt = new DataTable(); CFHMXdt.Columns.Add("group", typeof(System.String));  ...

  5. hadoop 蓄水池抽样 分布式抽样

    #!/usr/bin/env python # -*- coding=utf8 -*- import sys import os import random #input split 1565 #&g ...

  6. applicationContext&period;xml 配置(扫描)

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. easygui控件介绍

    1.msgbox: 语法:msgbox(text,title, ok_button='OK',image=None,root=None) 实例:msgbox('内容内容','标题标题','确定')返回 ...

  8. 小程序wx&period;getUserInfo获取用户信息方案介绍

    问题模块 框架类型 问题类型 API/组件名称 终端类型 操作系统 微信版本 基础库版本 API和组件 - -   - -     背景 小程序一个比较重要的能力就是获取用户信息,也就是使用 wx.g ...

  9. 创建dblink

    创建dblinkcreate database link user1_Link_app--dblink名称----connect to ehl_app ----远程数据库名称----identifie ...

  10. eclipse快键

    工作中经常用到的几个eclipse快捷键 ctrl+alt+箭头下或上-----------------复制当前行 ctrl+q -------------让光标返回最后一次修改的地方 ctrl+d ...