如何优雅的处理Nodejs中的异步回调

JavaScript06

如何优雅的处理Nodejs中的异步回调,第1张

Nodejs最大的亮点就在于事件驱动, 非阻塞I/O 模型,这使得Nodejs具有很强的并发处理能力,非常适合编写网络应用。在Nodejs中大部分的I/O操作几乎都是异步的,也就是我们处理I/O的操作结果基本上都需要在回调函数中处理,比如下面的这个读取文件内容的函数:

fs.readFile('/etc/passwd', function (err, data) {  if (err) throw err

console.log(data)

})

那,我们读取两个文件,将这两个文件的内容合并到一起处理怎么办呢?大多数接触js不久的人可能会这么干:

fs.readFile('/etc/passwd', function (err, data) {  if (err) throw err

fs.readFile('/etc/passwd2', function (err, data2) {    if (err) throw err   // 在这里处理data和data2的数据  })

})

那要是处理多个类似的场景,岂不是回调函数一层层的嵌套啊,这就是大家常说的回调金字塔或回调地狱(http://callbackhell.com/)的问题,也是让js小白最为头疼的问题。

这种层层嵌套的代码给开发带来了很多问题,主要体现在:

代码可能性变差

调试困难

出现异常后难以排查

本文主要是介绍如何优雅的处理以上异步回调问题。

初级方案:通过递归处理异步回调

我们可以使用递归作为代码的执行控制工具。把需要执行的操作封装到一个函数中,在回调函数中通过递归调用控制代码的执行流程,废话不多说,上个代码吧:

var fs = require('fs')// 要处理的文件列表var files = ['file1', 'file2', 'file3']function parseFile () {  if (files.length == 0) {    return

 }  var file = files.shift()

 fs.readFile(file, function (err, data) {    // 这里处理文件数据

   parseFile() // 处理完毕后,通过递归调用处理下一个文件  })

}// 开始处理parseFile()

以上代码已依次处理数组中的文件为例,介绍了通过递归的方式控制代码的执行流程。

应用到一些简单的场景中还是不错的,比如:我们将一个数组中的数据,依次保存到数据库中就可以采用这种方式。

通过递归的方式可以解决一些简单的异步回调问题。不过对于处理复杂的异步回调还是显得有些无能为力(如需要同步多个异步操作的结果)。

您好,你的问题,我之前好像也遇到过,以下是我原来的解决思路和方法,希望能帮助到你,若有错误,还望见谅!this关键字指向调用它的对象,test()是在GLOBAL中调用,而且异步函数回调应该形成了闭包,回调函数中的this也应该指向GLOBAL对象,而至于为啥this.vall是undefined,则是因为用var申明的变量都是局部变量,并不是GLOBAL变量的属性。

好好去看看javascript中this关键字指的对象和闭包的概念吧。希望能帮到你非常感谢您的耐心观看,如有帮助请采纳,祝生活愉快!谢谢!

异步处理不用阻塞来等待处理完成,而是允许后续操作,直至其程序将处理完成,并回调通知此函数

那么在js中有如下几种异步方式:

示例1

var async=function(callback){

    //read data

    setTimeout(function(){

        callback('data')

    },1000)//1秒后回调

}

//使用

async(function(data){

    alert(data)

})

示例2

var async=function(callback){

    var xhr=new XMLHttpRequest()

    xhr.open('get','.',true)

    

    xhr.onreadystatechange=function(){

        callback(xhr.readyStatus)

    }

    xhr.send()

}

async(function(data){

    alert(data)

})

示例3

var async=function(callback){

    var img=new Image()

    img.onload=img.onerror=function(){

        callback(img)

    }

    img.src='x.jpg'

}

async(function(data){

    alert(data)

})