gpt4 book ai didi

javascript - Node.js 中的异步代码和循环?

转载 作者:太空宇宙 更新时间:2023-11-04 00:52:47 25 4
gpt4 key购买 nike

我已经对异步编程进行了数小时的研究,但我似乎无法掌握 Node 中的这一单一概念,所以我想知道这里是否有人可以帮助我。

我编写了以下代码示例来返回/输出一个简单的字符串,该字符串是来自对象的字符串的串联:

var itemCollection = {
item1 : [{ foo : "bar" }, { foo : "bar" }, { foo : "bar" }],
item2 : [{ foo : "bar" }, { foo : "bar" }, { foo : "bar" }],
item3 : [{ foo : "bar" }, { foo : "bar" }, { foo : "bar" }]
}

var aString = "";

for(item in itemCollection){
for (var i = 0; i < itemCollection[item].length; i++) {
var anItem = itemCollection[item][i];

//someFunctionThatDoesALongIOOperation takes an item as a param, plus a callback.
someFunctionThatDoesALongIOOperation(anItem, function(dataBackFromThisFunction){
// Do something with the data returned from this function
aString += dataBackFromThisFunction.dataToAppend;
});
};
}

console.log(aString);

因此,根据我的理解,Javascript 以外的语言将someFunctionThatDoesALongIOOperation 同步运行,并且脚本将以“阻塞模式”运行。这意味着值 aString 将以其正确的值返回/输出。

但是,由于 Node 异步运行,代码可以随时继续运行,任务可能无法按顺序完成。这是因为事件循环在 Node 中的工作方式。我想我明白了。

所以这就是我的问题所在。如果我希望像在其他语言中一样返回/输出值 aString 及其正确值,我需要对代码示例中的循环做什么?或者用更技术性的措辞来表达我的问题:使 aString 返回预期结果的正确方法是什么,以便在脚本执行完成后,当 aString 已经返回时,IO 操作(需要更长的时间来运行)不会完成?

我希望我的问题有意义,如果没有,请告诉我,我会在适当的情况下进行编辑。

谢谢

最佳答案

由于应用于每个项目的函数是异步的,因此处理它们的循环也必须是异步的(同样,使用此循环结果的函数也必须是异步的)。查看Bob Nystrom's "What Color is Your Function?"有关这一点的更多见解。

有两种方法可以做到这一点(都使用 caolan's async library 来包装所有讨厌的回调逻辑):

  • 一次执行一个异步操作,等待前一个操作完成后,下一个操作才能开始。这可能与传统同步循环的运行方式最相似。我们可以用 async.reduce 来做到这一点:

    async.reduce(itemCollection, "", function(memo, item, callback) {
    someFunctionThatDoesALongIOOperation(item, function(dataBackFromThisFunction) {
    callback(null, memo + dataBackFromThisFunction.dataToAppend);
    });
    }, function(err, result) {
    var aString = result;
    });
  • 当然,如果我们没有真正获得异步代码的好处并同时执行许多事情,那么拥有异步代码就没有什么意义。我们可以并行执行所有异步操作,然后在一个步骤中一次性减少所有操作。我发现如果处理每个项目需要一些长时间操作(例如网络 I/O),这非常有用,因为我们可以立即启动并等待许多请求。我们使用async.map实现这一目标:

    async.map(itemCollection, function(item, cb) {
    someFunctionThatDoesALongIOOperation(item, function(dataBackFromThisFunction) {
    cb(null, dataBackFromThisFunction.dataToAppend);
    });
    }, function(err, results) {
    var aString = results.join('');
    });

关于javascript - Node.js 中的异步代码和循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31600040/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com