什么是回调地狱以及如何在 Node.js 中避免它?
在本文中,我们将了解回调地狱以及如何避免它。回调地狱是我们有复杂的嵌套回调的情况。正如我们已经提到过“回调”这个术语,所以在深入了解回调地狱的细节之前,让我们先了解一下回调是什么?回调是在完成特定任务时自动调用的函数。基本上,它允许程序运行其他代码,直到某个任务没有完成。此函数允许您执行大量可由操作系统处理的 I/O 操作,而无需等待任何 I/O 操作完成,这使得 nodeJs 具有高度可扩展性。
句法:
const fs = require("fs");
fs.readFile("file_path", "utf8", function (err, data) {
if (err) {
// Handle the error
} else {
// Process the file text given with data
}
});
什么是回调地狱?
Node.js 中的回调地狱是我们有复杂的嵌套回调的情况。在这种情况下,每个回调都接受作为先前回调的结果而获得的参数。这样,代码结构看起来像金字塔,可读性差,维护难度大。此外,如果一个函数出现错误,那么所有其他函数都会受到影响。
创建结构:
第 1 步:首先,使用以下文本创建一个文本文件 input.txt:
Welcome to GFG.
Learn NodeJS with GeeksforGeeks
第 2 步:现在,创建一个名为 main.js 的 javascript 文件。
项目结构:
示例:这是回调地狱的一个简单示例。我们可以看到代码中有嵌套的回调,这使得代码更难理解。
Javascript
var fs = require("fs");
var textFile = "input.txt";
fs.exists(textFile, function (exists) {
if (exists) {
fs.stat(textFile, function (err, res) {
if (err) {
throw err;
}
if (res.isFile()) {
fs.readFile(textFile,
"utf-8", function (err, data) {
if (err) {
throw err;
}
console.log(data);
});
}
});
}
});
Javascript
var fs = require('fs');
const fsPromises = require('fs').promises;
fs.promises.readFile("input.txt")
.then(function (data) {
console.log("" + data);
})
.catch(function (error) {
console.log(error);
})
运行服务器:现在运行 main.js 以使用以下命令查看结果:
node main.js
输出:
在这个例子中,我们有一个 nodeJS 的 fs 模块,它提供了文件 I/O 操作的功能。借助 exists()函数,我们可以测试给定路径是否存在于文件系统中。如果它存在,我们在其中定义了一个函数。因此在这个例子中,我们在另一个函数中定义函数,这给我们带来了回调地狱问题,因为它很难理解和阅读代码。
如何避免“回调地狱”?
- Promise:在 Promise 的帮助下,可以避免回调地狱。 javascript 中的 Promise 是在 Node.js 中处理异步操作的一种方式。它允许我们从异步函数(如同步函数)返回一个值。当我们从异步方法返回某些内容时,它会返回一个 Promise,当它在未来可用时,可以在 then() 方法或异步函数内部的 await 的帮助下使用该最终值。下面提到了创建 Promise 的语法。
句法:
const promise = new Promise(function (resolve, reject) {
// code logic
});
示例:在这个示例中,我们正在借助 Promise 读取名为“input.txt”的纺织品。创建一个 javascript 文件名 main.js 并编写以下代码:
Javascript
var fs = require('fs');
const fsPromises = require('fs').promises;
fs.promises.readFile("input.txt")
.then(function (data) {
console.log("" + data);
})
.catch(function (error) {
console.log(error);
})
运行服务器:现在运行 main.js 以使用以下命令查看结果:
node main.js
输出:
在这个例子中,我们有一个 nodeJS 的 fs 模块,它提供了文件 I/O 操作的功能。然后我们在 fs.promises.readfile 方法的帮助下读取文件,该方法返回一个 promise。
- Async.js:另一种避免回调地狱的方法是,我们有一个名为 Async 的 npm 模块。 Async 有助于管理异步 JavaScript。一些有用的异步方法是串行、并行、瀑布等。它也适用于浏览器。
安装:
npm i async
- 为了避免回调,我们应该避免在程序中使用两个以上的嵌套回调函数,因为这将有助于保持代码的可读性。