Nodejs--异步编程

发布于:2024-04-22 ⋅ 阅读:(175) ⋅ 点赞:(0)

异步编程

函数式编程

高阶函数

在通常的语言中,函数的参数只接受基本的数据类型或者是对象引用,返回值只能是基本数据类型和对象引用。

function foo(x) {
  return x
}

高阶函数是把函数作为参数,将函数作为返回值的函数

function foo(x) {
  return function () {
    return x
  }
}

高阶函数可以将函数作为输入或者返回值的变化

偏函数用法

偏函数用法是指创建一个调用另外一个部分(参数或者变量已经预置的函数)的函数的用法

var toString = Object.prototype.toString
var isString = function(obj) {
  return toString.call(obj) === '[object String]'
}
var isFunction = function(obj) {
  return toString.call(obj) === '[object Function]'
}

在JavaScript中进行类型判断的时候,通常会进行类型上述代码的方法进行定义,但是上面的代码出现了冗余代码,为了解决重复定义的问题,引入一个姓的函数,这个新的函数可以和重唱一样批量创建类似的函数

var isType = function(type) {
  return function (obj) {
    return toString.call(obj) == '[object' + type + ']'
  }
}
var isString = isType('String')
var isFunction = isType('Function')

== 这种通过指定部分参数类产生一个新的定制函数的形式叫偏函数==

异步编程的优势和难点

node带来的最大特性:事件驱动的非阻塞I/O模型。非阻塞io可以使得cpu和io并不相互依赖等待,让资源得到更好的利用,对于网络引用而言,并行带来的想象空间更大
在这里插入图片描述

如果采用传统的同步io模型,分布式计算中的性能会大打折扣
在这里插入图片描述

难点

异常处理

异步io的实现主要包括两个阶段,提交请求和处理结构,这两个阶段中又事件循环的调度,两者互不关联,异步方法通常在第一个阶段请求后立即返回,因为异常不一定发生在这个阶段。

var async = function(callback) {
    process.nextTick(callback)
}

调用async()方法后,callback被存储起来,直到下一次tick才会取出来,尝试用异步方法进行try/catch操作只能捕获档次时间循环内的一场,对于callback执行时抛出的异常无能为力

try {
    async(callback)
}catch(e) {
//todo
}

node在一场处理上形成了一种约定: 将异常作为回调函数的第一个实参传回,如果是空值,则表明调用没有异常抛出

async(function (err, results) {
    //todo
})
  1. 必须执行调用者传入的回调函数
  2. 正确传递回异常供调用者判断
var async = function(callback) {
    process.nextTick(function() {
    var results = something
    if(error) {
        return callback(error)
    }
    callback(null, results)
})
}

在异步方法的编写中,另一个容易犯的错误是对用户传递的回调函数进行异常捕获

  • 错误
try {
    req.body = JSON.parse(buf, options.reviver)
    callback()
} catch(err) {
    err.body = buf;
    err.status = 400
    callback(err)
}
  • 正确
try {
    req.body = JSON.parse(buf,options.reviver)
} catch(err) {
    err.body = buf;
    err.status = 400
    return callback(err)
}
callback()
函数嵌套过深

dom事件相对而言不会存在相互依赖或者需要多个事件一起写作的场景,较少出现异步多级依赖的情况,但是对于node而言,事务中存在多个异步调用的场景

fs.readdir.join(__dirname, '..'), function(err, files) {
    files.forEach(function(filename, index){
        fs.readFile(filename, "utf8",function(err, file) {
        })
    })
}
阻塞代码

node中没有sleep()

var start = new Date()
while(new Date() - start < 1000 ) {
 //  todo
}
// 需要阻塞的代码

这段代码是糟糕的,会一直占用cpu进行判断,并不能让进程沉睡

多线程编程

在谈论JavaScript的时候,通常是单一线程上的代码,浏览器中指的是JavaScript执行线程和ui渲染共用的一个线程,在node中,没有ui渲染的部分。模型基本相同,对于服务器端,单个node不会充分利用多核cpu的,web workers 通过对JavaScript执行和ui渲染分开,更好的利用了多核cpu进行大量运算。
在这里插入图片描述

前端浏览器对于标准的之后性,web worker没有应用起来。web worker能利用cpu喝减少阻塞ui渲染,但是不能解决ui渲染的效率问题,node借鉴了这个模式。

异步转同步

node中同步编程,不能得到原生手段的支持,需要借助库或者编译手段来实现。对于异步调用,存在良好的流程控制。


网站公告

今日签到

点亮在社区的每一天
去签到