最近几天我一直在思考JavaScript。许多框架仅以异步/承诺方式提供功能。但是,由于我以前用同步语言(PHP,Python,......)编程,我会遇到一些基本的想法。
例如:
我们假设我们有函数nextValue()
,它从某些单词列表中返回字符串。我们的任务是找到" Foo"在此列表中打印索引所在的" Foo"单词位于。
如果nextValue()
函数是同步的,我们可以很容易地做到:
var found = false;
for (var i = 0; !found; i++) {
if (nextValue() == 'Foo') {
console.log("'Foo' found at index " + i);
found = true;
}
}

但是如果函数是异步的,我唯一的想法就是创建函数并递归调用它,直到我们找到" Foo"字:
var i = 0;
(function checkNextValue(){
nextValue(function(value){
if (value == 'Foo') {
console.log("'Foo' found at index " + i);
} else {
i++;
checkNextValue();
}
});
})();

但我在这里看到的问题很少:
return
值,我们被迫使用再次回调或承诺)。 我在这里缺少什么?谢谢你的想法:-)
答案 0 :(得分:2)
如何正确创建具有异步功能的循环?
Javascript采用迭代的概念,更可能是其他语言的概念,因此,迭代并不真正关注同步/异步代码执行。有很多方法可以实现异步迭代:
是更干净,更有说服力的方式。
异步示例更难阅读。想象一下,如果我们需要两个嵌套循环甚至更多。
Async
代码执行通常比同步代码更难阅读,顺便说一句,你可以写一个干净的方式。让我们实现像Array#extras
Array.prototype.asyncForEach = function asyncForEach(callback, context = null) {
const self = this;
let index = 0;
function iterate() { setTimeout(iteration, 1500); }
function iteration() {
callback.call(context, self[index], index, self);
index += 1;
if(self.length > index) {
iterate();
}
}
return iterate();
};
['hello dear', 'how are you?', 'I am fine, thanks']
.asyncForEach((item, index, list) => {
console.log(Date.now(), `Iteration at {i: ${index}}`, item);
})
;
RAM使用情况。如果“Foo”值在索引1000处怎么办?内存中将有1000个正在运行的函数“感谢”递归。
当然RAM的使用是一个很大的问题,但是,你必须要记住,Javascript基于non blocking I/O,因此,你的异步迭代将花费少于正常的同步代码。
一般来说这很复杂,编写代码要困难得多,甚至在其他地方重用代码(我们不能简单地返回值,我们不得不再次使用回调或承诺)。
对于所有语言,你在这里很新,只要你继续使用Javascript就会觉得很舒服!