关于nodejs中的异步编程的理解

从一个简单的案例开始

依次读取a.txt 、 b.txt 、 c.txt 的内容
a.txt

this is a

b.txt

this is b

c.txt

this is c

如果按照一般的方法,a b c中的文件不会依次读出,会打乱顺序的

nodejs 特点是单线程、异步,如果代码逻辑涉及到多个回调,就会出现非常可怕的代码,不利于后期的维护。

对于异步的理解

当一段代码中同时有同步代码和异步代码时,他会先执行同步的代码,将异步的代码放到一边,最后在执行,而这样的话就会产生很大的问题,不能够及时获取到信息

异步编程的解决方案

有一种最古老的办法就是回调

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)

        })
    })
})

这样的话,容易产生回调地狱的问题,一旦代码多了就容易出问题

1.promise

Promise对象具备then方法,接受完成态、失败态的调用,只接受function对象,其余对象将被忽略。then方法继续返回Promise对象,以实现链式调用。

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')

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)
})

调用then方法时才会立即执行 resolve(data) ,这样的链式就减少了代码的嵌套

2.async和await

const fs = require('fs')
function readFile(path) {
    return new Promise((resolve, reject) => {
        fs.readFile(path, 'utf8', (err, data) => {
            resolve(data)
        })
    })
}

async function exec() {
    await readFile('./file/a.txt').then(result => console.log(result))
    await readFile('./file/b.txt').then(result => console.log(result))
    await readFile('./file/c.txt').then(result => console.log(result))
}
exec()
  • await后面接一个会return new promise的函数并执行它
  • await只能放在async函数里
  • 为什么要用await
    为了使我们的异步代码,看起来更像同步的代码

await等到以后做了什么事情?

如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async里面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。

猜你喜欢

转载自blog.csdn.net/WenR_zt/article/details/104801660