for循环内的回调函数-Nodejs
Posted
技术标签:
【中文标题】for循环内的回调函数-Nodejs【英文标题】:Callback function inside for loop - Nodejs 【发布时间】:2021-05-28 22:48:36 【问题描述】:希望你今天过得愉快。我最近发现在for
循环中处理回调并不容易。我尝试了几件事,但找不到解决方案。
代码如下:
var book = new Array;
var chapters = Object.keys(epub.spine.contents).length;
for (let i = 0; i < chapters; i++)
let cacheArray = [];
epub.getChapter(epub.spine.contents[i].id, function (err, data)
if (err)
return console.log(err);
//remove html tags
let str = data.replace(/<\/?[\w\s]*>|<.+[\W]>/g, '');
book.push(str)
)
console.log(book)//returns empty array ofc
这段代码执行后,我需要遍历数组来搜索它的内容。如果不是这样,我的方法是将其发送到数据库。
我的方法如下:
var recursiveChapter = function (n)
var book = new Array;
if (n < chapters)
// chapter function
epub.getChapter(epub.spine.contents[n].id, function (err, data)
if (err)
throw err
//remove HTML tags
let str = data.replace(/<\/?[\w\s]*>|<.+[\W]>/g, '');
book.push(str)
recursiveChapter(n + 1)
);
//start the recursive function
recursiveChapter(0)
console.log(book)//returns an empty array
我被困住了,想不出一种在不将其存储在数据库中的情况下使用这些数据的方法。 任何帮助将不胜感激。
【问题讨论】:
你能告诉我们你期望这段代码做什么以及你目前面临什么? 为什么不承诺您的getChapter
功能。等待这个方法会更容易
@AliHussam getChapter 来自外部库,所以是的,我可以修改它,但我认为这需要一些时间。 (github.com/julien-c/epub) 这个库顺便说一句。
@arminyahya 这个函数基本上将一个 epub 解析为一个字符串,一旦它完成了,我就可以通过事件发射器与之交互。一旦我在那里,我需要加载每一章并删除 html 标签,将每一章推入一个数组,然后我想用 forEach 循环进行搜索。我遇到的问题是 getChapter 返回一个回调,所以 for 循环继续运行,如果我尝试使用数组,它总是空的,所以我不能继续我刚才提到的过程。
你的函数有一个错误的第一个回调,你可以简单地做util.promisify
来承诺它或为此调用编写一个承诺的包装器。
【参考方案1】:
有几种方法可以解决这个问题。一种方法是使用async library,这允许异步运行。并行或串行调用。
例如,我们可以使用async.mapSeries()将一系列异步调用的结果作为一个数组来获取。
您输入您的 id 数组,然后回调将返回一个返回数据的数组,例如,我已经模拟了 getChapter() 函数以让您了解它的工作原理:
// Mock out epub object
const epub =
getChapter(id, callback)
setTimeout(() => callback(null, "Data for id " + id), 250);
let ids = [1,2,3,4];
console.log("Calling async.mapSeries for ids:", ids);
async.mapSeries(ids, epub.getChapter, (err, result) =>
if (err)
console.error(err);
else
console.log("Result:", result)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/3.2.0/async.min.js" integrity="sha512-6K6+H87tLdCWvY5ml9ZQXLRlPlDEt8uXmtELhuJRgFyEDv6JvndWHg3jadJuBVGPEhhA2AAt+ROMC2V7EvTIWw==" crossorigin="anonymous"></script>
您也可以承诺 epub 调用并使用 Promise.all 来获取结果,如下所示:
epub =
getChapter(id, callback)
setTimeout(() => callback(null, "Data for id " + id), 250);
let ids = [1,2,3,4];
function getChapterPromisified(id)
return new Promise((resolve, reject) =>
epub.getChapter(id, (err, data) =>
if (err)
reject(err);
else
resolve(data);
)
)
// Create a list of promises, one for each call
const promises = ids.map(id => getChapterPromisified(id))
Promise.all(promises)
.then(result => console.log("Result:", result))
.catch(error => console.error("An error occurred:", err));
【讨论】:
感谢 Terry 的回复,我使用的函数来自外部库(确切地说是 github.com/julien-c/epub),所以我认为我无法修改它。我的意思是,我当然可以,但这可能需要我一些时间,因为我真的不知道它是如何制作的(这个github.com/julien-c/epub)。你的第一个答案,这可能有效,因为我有办法获得身份证。我要试一试,谢谢。 感谢您测试我的答案!您不必修改该功能,如果您想走承诺路线,也许只需添加一个包装器。如果您使用异步方法,则根本不需要修改函数! 哦,对了,我可以包装它并返回一个承诺,我没有想到这一点。你看,我是人们所说的“菜鸟”,所以我从来没有真正尝试过,但它看起来很有趣,我要去看看。非常感谢。 哦,太好了,试试这些方法。只需测试一下,看看是否适合您! 第二个工作得很好,我遇到了一些问题,只是因为我忘了实际兑现承诺,这让我发疯了几个小时。谢谢你!以上是关于for循环内的回调函数-Nodejs的主要内容,如果未能解决你的问题,请参考以下文章
将索引从 for 循环传递到 ajax 回调函数 (JavaScript)
js的for循环中出现异步函数,回调引用的循环值总是最后一步的值?
js的for循环中出现异步函数,回调引用的循环值始终是最后的值