异步JavaScript:正确的循环方式?

时间:2017-08-08 08:45:23

标签: javascript asynchronous

最近几天我一直在思考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();
        }
    });
})();




但我在这里看到的问题很少:

  1. 异步示例更难阅读。想象一下,如果我们需要两个嵌套循环甚至更多。
  2. RAM使用情况。如果" Foo"价值将在1000指数?内存中将有1000个运行功能"感谢"到递归。
  3. 一般情况下很复杂,编写代码要困难得多,甚至在其他地方重复使用代码(我们不能简单return值,我们被迫使用再次回调或承诺)。
  4. 我在这里缺少什么?谢谢你的想法:-)

1 个答案:

答案 0 :(得分:2)

  

如何正确创建具有异步功能的循环?

Javascript采用迭代的概念,更可能是其他语言的概念,因此,迭代并不真正关注同步/异步代码执行。有很多方法可以实现异步迭代:

  1. Iterators and Generators
  2. Observables
  3. Async Iteration
  4. 是更干净,更有说服力的方式。

      

    异步示例更难阅读。想象一下,如果我们需要两个嵌套循环甚至更多。

    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就会觉得很舒服!