nodejs中异步的四种同步写法

本文探讨了Node.js中如何通过回调函数、Promise、co+生成器和Async将异步操作转换为同步,以及四个示例展示它们在文件读取中的使用。同时,解释了Promise和setTimeout执行顺序的原理,以及常见误区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么要写成同步
nodejs是单线程的,为了避免阻塞,在进行io操作的时候为了就采用异步执行的方式.但是很多时候异步执行会带来很多麻烦,比如我们读文件,拿到文件数据再进行操作,这个时候如果异步那么就会打不到想要的效果
那么就有了把异步改成同步的方法,在js的发展历程中一共出现了四种异步改成同步的方式

方式一:回调函数

const fs = require("fs")

//第一阶段,回调函数
function readFile(cb){
    fs.readFile('./package.json',(err,data)=>{
        if(err){
            return cb(err)
        }else{
            cb(null,data)
        }
    })
}

readFile((err,data)=>{
    if(!err){
        data = JSON.parse(data)
        console.log(data)
    }else{
        console.log("failed")
    }
})



方式二:Promise

function readFileAsync(path){
    return new Promise((resolve,reject)=>{
        fs.readFile(path,(err,data)=>{
            if(err) reject(err)
            else resolve(data)
        })
    })
}

readFileAsync('./package.json')
    .then(data => {
        data =JSON.parse(data)
        console.log(data)
    })
    .catch(err => {
        console.log(err)
    })



方式三:co+生成器+util

const co = require("co")

const util = require('util')

co(function *(){
    let data = yield util.promisify(fs.readFile)('./package.json')
    data = JSON.parse(data)
    console.log(data)
})


方式四:Async

const readAsync = util.promisify(fs.readFile)

async function init(){
    let data = await readAsync('./package,json')

    data = JSON.parse(data)

    console.log(data)
}


几个关于异步的题目
1.

var p = new Promise((resolve, reject) => {
    resolve(3) // 这里是一定会异步操作
})

p.then(v => console.log(v,'1'))
p.then(v => console.log(v,'2'))
p.then(v => console.log(v,'3'))
console.log(4)


首先promise类型都是放入队列的,遇到io操作,promise都放入队列,所以先打印4,再以此打印1,2,3

2.

console.log(1)
const p = new Promise((resolve, reject) => {
    console.log(2)
    setTimeout(() => console.log(3), 0)
    resolve(4)
})
p.then(v => console.log(v))
console.log(5)


先打印1
再打印2
遇到settimeout放入别的线程
promis进入队列
打印5
打印promise
打印settimeout
所以答案是1.2.5.4.3

这里有一个问题,就是为什么timeout设置的是0但是确实最后执行的?公司的师兄给我的解释是这在一个单独的现场里,所以什么时候运行不可预期,一般来说在一个for循环里的settimeout都是最后执行.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值