Nodejs
Nodejs本身是单线程的,底层核心库是Google开发的V8引擎,而主要负责实现Nodejs的异步功能的是一个叫做libuv的开源库,github上可以找到它。
异步编程
Nodejs异步编程是指执行到一个方法的时候,不立即执行,而是加入到队列,然后接着往下执行,Nodejs内部是适时执行队列的方法,执行完执行回调方法(如果有回调方法)。由于只Nodejs 是单线程,异步编程模型保证了Nodejs快速响应,充分利用CPU。
下列代码是打印根目录下一个名为a的txt文件内容
const fs = require(‘fs’)
const path = require(‘path’)
let a_path = path.join(__dirname, ‘file’, ‘a.txt’)
fs.readFile(a_path, ‘utf8’, (err, data) => {
if (err) throw err
console.log(data)
})
因为fs.read()本身是一个异步函数,所以返回值是异步的,必须在回调函数中捕获,所以需要这样写,但是一两个异步还好,但是如果多了的话,就是程序员的噩梦之一回调地狱
回调地狱
const fs = require(‘fs’)
const path = require(‘path’)
let a_path = path.join(__dirname, ‘file’, ‘a.txt’)
let b_path = path.join(__dirname, ‘file’, ‘b.txt’)
let c_path = path.join(__dirname, ‘file’, ‘c.txt’)
fs.readFile(a_path, ‘utf8’, (err, data) => {
if (err) throw err
console.log(data)
fs.readFile(b_path, ‘utf8’, (err, data) => {
if (err) throw err
console.log(data)
fs.readFile(c_path, ‘utf8’, (err, data) => {
if (err) throw err
console.log(data)
})
})
})
连续的回调函数的嵌套,会使得代码变得冗长,易读性大幅度降低并且难以维护,这种情况被称作回调地狱,所以为了解决这个问题,ES标准推出了一套异步编程解决方案
Promise
promise本身是一个对象,但是可以看做是是一种工具,用来解决的是Nodejs异步接口串行执行导致的回调地狱问题,它本身对代码逻辑没有影响
以下代码是promise的异步代码
function readFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, ‘utf8’, (err, data) => {
resolve(data)
})
})
}
let p1 = readFile(a_path)
p1.then(data => {
console.log(data)
return readFile(b_path)
}).then(data => {
console.log(data)
return readFile(c_path)
}).then(data => {
console.log(data)
})
与之前的异步代码不同的是,我们在异步函数外层包了一层返回promise对象的函数,promise对象向自己包裹的函数里传入了两个函数参数resolve和reject,在异步函数内部通过调用resolve向外传递操作成功数据,调用reject向外传递错误信息。
总结一下异步编程:多个方法各自实行,互不干涉,不像是同步编程,只有上面的执行完毕才可以进行下面的代码,异步编程的优点就是以这种方式写出的代码可读性可维护性可以说是非常强,完全没有之前的回调地狱带来的副作用