Node.js 中,同步和异步代码有什么区别?

八股文一网打尽,更多面试题请看程序员面试刷题神器 - 面试鸭open in new window

回答重点

在 Node.js 中,同步代码(Synchronous Code)和异步代码(Asynchronous Code)是编程中的两种重要方式。它们的主要区别在于代码的执行顺序和阻塞行为:

1)同步代码:这种代码在执行的时候会阻塞后续代码的执行,直到当前操作完成。所以在同步代码中,每一步操作都必须等待前一步操作完成后再继续执行。

2)异步代码:这种代码不会阻塞后续代码的执行。异步操作会在完成时通过回调函数、Promise 以及 async/await 等机制通知相关的代码片段去处理结果。

举个简单的例子来对比:

// 同步代码
const fs = require('fs');
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data); // 此时,代码会等待文件读取完成再执行后面的代码
console.log('Done'); // 这行代码会在文件读取完成后执行

// 异步代码
fs.readFile('file.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data); // 文件读取完成时,这个回调函数才会被执行
});
console.log('Done'); // 这行代码会被立即执行,不会等待文件读取完成

扩展知识

理解同步和异步代码的区别对 Node.js 编程非常重要,因为 Node.js 本质上是单线程的,但会通过事件驱动和异步 I/O 操作来实现高效性能。我补充一些相关的知识点供你参考:

1)事件驱动架构(Event-Driven Architecture):Node.js 使用 libuv 库来处理异步事件。事件循环(Event Loop)不断检查是否有事件需要处理,并执行相应的回调函数。这使得 Node.js 非常适合处理 I/O 密集型任务。

2)非阻塞 I/O(Non-Blocking I/O):Node.js 天生支持非阻塞 I/O 操作,这意味着它可以在等待 I/O 操作(如文件读取、网络请求)完成的同时,继续处理其他任务。这对于处理大量并发请求特别有用。

3)串行化控制异步代码:处理异步代码的一些常见方法包括使用回调函数、Promise、async/await 等。特别是 async/await,使得异步代码看起来更像是同步代码,显得更直观易读。

示例:使用 Promise 和 async/await 重新编写异步文件读取代码

const fs = require('fs').promises;

// 使用 Promise
fs.readFile('file.txt', 'utf8')
    .then(data => {
        console.log(data); // 文件读取完成后的处理
    })
    .catch(err => {
        console.error(err); // 错误处理
    });
console.log('Done'); // 这行代码会被立即执行

// 使用 async/await
(async () => {
    try {
        const data = await fs.readFile('file.txt', 'utf8');
        console.log(data); // 文件读取完成后的处理
    } catch (err) {
        console.error(err); // 错误处理
    }
    console.log('Done'); // 在文件读取完成后执行
})();

八股文一网打尽,更多面试题请看程序员面试刷题神器 - 面试鸭open in new window

最近更新:
Contributors: weave