node异步

本文深入探讨了Node.js中的异步编程,通过示例讲解了异步函数如何工作,包括异步读取文件的实现方式。同时,文章对比了回调函数和Promise方法在处理异步操作时的优劣,展示了如何使用Promise简化异步流程。

node异步

异步函数就是当同步线程执行结束之后,才会开始执行异步队列中的函数
例如:readFile()


异步读取文件

const fs = require('fs');
fs.readFile('a.txt', (err, data) => {
	console.log('文件开始读取');
});
console.log('结束文件读取');

输出结果

结束文件读取
文件开始读取

依次读取A文件、B文件、C文件

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)

        })
    })
}

简单的逻辑下,回调函数使用还是不错的,但在复杂的逻辑,会有很多层的函数嵌套,很难看清楚整个流程。也不好改动
然后使用
Promise方法

const fs = require('fs')
function p1(){
    return new Promise((resolve,reject)=>{
        fs.readFile('1.txt','utf8',(err,data)=>{
             resolve(data)
        })
    })
}
function p2(){
    return new Promise((resolve,reject)=>{
        fs.readFile('2.txt','utf8',(err,data)=>{
              resolve(data)
        })
    })
}
function p3(){
    return new Promise((resolve,reject)=>{
        fs.readFile('3.txt','utf8',(err,data)=>{
             resolve(data)
        })
    })
}
p1().then(result=>{
    console.log(result)
    return p2()
}).then(result=>{
    console.log(result)
    return p3()
}).then(result=>{
    console.log(result)
    return p2()
})

将重复的代码封装到一个函数中,需要时直接调用
then方法
Promise对象实例构建完毕的时候,可以通过then方法对状态进行处理,then方法有两个参数,分别是成功时候的回调和失败时候的回调函数。

Node.js 中,模块化是一种将程序分解为多个独立模块的编程设计思想,每个模块封装了特定的功能,并且可以通过特定的接口与其他模块进行交互。这种模块化的设计思想在异步导出模块时同样适用,Node.js 提供了多种机制来实现异步模块导出。 ### 使用 `module.exports` 和 `require` 进行同步模块导出 Node.js 每个模块都有一个 `module.exports` 对象,开发者可以通过该对象暴露模块的接口,以供其他模块使用。Node.js 会自动将 `module.exports` 的内容返回给 `require` 调用者。这种方式适用于同步导出模块成员[^4]。例如: ```javascript // test.js exports.n1 = 10; exports.hello = function() { return "Hello from module"; }; ``` ```javascript // main.js const test_module = require('./test'); console.log(test_module.n1); // 输出 10 console.log(test_module.hello()); // 输出 "Hello from module" ``` ### 异步导出模块的方法 尽管 `module.exports` 和 `require` 是同步的,但在某些情况下,可能需要异步加载模块或执行初始化逻辑。Node.js 支持通过 Promise 或 async/await 来实现异步模块导出。一种常见的做法是将异步操作封装在一个函数中,并将其导出,供其他模块调用。 #### 示例:使用 async/await 导出模块功能 假设某个模块需要从远程 API 获取数据并导出: ```javascript // dataModule.js const axios = require('axios'); async function fetchData() { try { const response = await axios.get('https://api.example.com/data'); return response.data; } catch (error) { throw new Error(`Failed to fetch data: ${error.message}`); } } module.exports = { fetchData }; ``` ```javascript // main.js const dataModule = require('./dataModule'); dataModule.fetchData() .then(data => console.log('Fetched data:', data)) .catch(err => console.error(err)); ``` 在这个例子中,`fetchData` 是一个异步函数,它返回一个 Promise。调用者可以使用 `.then()` 和 `.catch()` 来处理异步结果[^2]。 ### 使用模块内部的异步初始化逻辑 有时模块本身需要进行一些异步初始化工作(如连接数据库、读取配置文件等),这些操作不能直接放在 `module.exports` 中完成。此时可以采用工厂模式,提供一个异步初始化方法,返回一个 Promise,确保模块在初始化完成后才被使用。 #### 示例:异步初始化模块 ```javascript // dbModule.js let dbConnection = null; async function connectToDatabase() { // 模拟异步数据库连接 return new Promise((resolve, reject) => { setTimeout(() => { dbConnection = { query: (sql) => `Executing: ${sql}` }; resolve(dbConnection); }, 1000); }); } async function init() { if (!dbConnection) { await connectToDatabase(); } return { query: (sql) => dbConnection.query(sql) }; } module.exports = { init }; ``` ```javascript // main.js const dbModule = require('./dbModule'); dbModule.init().then(db => { console.log(db.query('SELECT * FROM users')); }); ``` 此方式允许模块在异步初始化后才提供其功能,确保模块状态正确[^3]。 ### 注意事项 - **避免全局变量导出**:通过 `global.xxx` 方式导出不符合 CommonJS 规范,不推荐使用。 - **模块导入需谨慎**:无论通过哪种方式导出,使用时都需要先导入 (`require`) 才能使用。 - **异步模块管理**:当模块依赖异步操作时,应确保调用方能够处理 Promise 或异步函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值