Node.js CPS回调
一只大加号 人气:0前言
前面我们介绍了node的基础模块,今天我们来实践一个更加进阶的写法,那就是node的异步处理,由于过多的事件堆积在一起嵌套使用容易引起回调地狱,所以在日常开发中异步的使用显得异常的重要,在开发中我们也经常会遇到某些接口需要先后调用的问题,那么异步是一个很好的解决方案,所以今天来给这个知识点做一个笔记。
嵌套回调
我们先用一个小栗子,书写一个方法接受一个参数并将参数读取的数据返回,简单来封装一个文件读取的方法。
var fs = require('fs'); function read(path){ fs.readFile(path,function(err,data){ return data; }) } let a = read('a.txt'); console.log(a);
//如果存在多个需要读取的文件,而由于各个文件的大小不相同,可能读取的速度也不同,这样的话可能会导致执行后返回的顺序不一样,但如果我们需要读取的文件是有顺序的,那这样就会造成一些问题了 read(a.txt) read(b.txt) read(c.txt)
回调地狱
如果我们不用异步进行解决,我们需要在读取b文件之前需要用到a文件之间的某些信息,那么我们是需要在a文件读取完成之后再进行执行读取b的操作,通常是这么写的
fs.readFile(path,function(err,data){ console.log(data); fs.readFile(Path2D,function(err,data){ console.log(data); }) })
如果我们只是单纯的这么写,看上去确实是没有问题的,因为我们只需要用来读取来个文件,但如果文件相互依赖比较多的话,需要用到的嵌套回调会更多,这样就会形成所谓的回调地狱的问题。不仅嵌套的层数增加,代码的可维护性也变得更低
回调与CPS
将回调函数作为参数传递,这种书写方式通常被称为Continuation Passing Style(CPS),它的本质仍然是一个高阶函数,CPS最初是各大语言中对排序算法的实现。
CPS风格回调:
var callBack = function(err,data){ if(err){ console.log(err); } console.log(data.toString());//666 } fs.readFile('./异步/aaa.txt',callBack);
如果重复调用了readFile都是同一个回调的话,那么CPS可以帮我们节省掉很多的代码,如果是多个回调不相同的情况下,CPS可以在一定程度上解决回调嵌套的问题
var callBack = function(err,data){ if(err){ console.log(err); }else{ fs.readFile('./异步/a2.txt',callBack2); } } var callBack2 = function(err,data){ if(err){ console.log(err); }else{ fs.readFile('./异步/a3.txt',callBack3); } } var callBack3 = function(err,data){ if(err){ console.log(err); }else{ // fs.readFile('./异步/a3.txt',callBack3); } } fs.readFile('./异步/a1.txt',callBack);
我们可以看出来CPS的回调比嵌套回调更加的美观一点,但是业务逻辑仍然散发在不同的callback中,代码还是会显得比较冗余,我们下一节来看一下async模块对回调的简化
加载全部内容