• javascript 异步循环 asyncEach


    来自

    http://blog.jcoglan.com/2010/08/30/the-potentially-asynchronous-loop/

    (可能已被墙)

    写程序时候经常会碰到这种情况,有一个队列,对这个队列进行一次操作会相当消耗性能,因此需要对队列中每个元素独立进行操作,一个接一个。如果这个操作是阻塞的话 用一个for循环就搞定了,如果是异步操作呢。

    比如,有一个url数组,需要轮流访问每一个url,上一个返回后才进行下一个

    listOfUrls.forEach(function(url) {  
        $.get(url, function(response) {  
            // handle response  
        });  
    });  
    

    以上代码显然是不满足要求的,所有请求将一次发送出去,而不是一个接一个。下面介绍这样的异步forEach:

    Array.prototype.asyncEach = function(iterator) {  
        var list = this,  
            n = list.length,  
            i = - 1;  
        var resume = function() {  
            i += 1;  
            if (i === n) return;  
            iterator(list[i], resume);  
        };  
        resume();  
    };  

    以上代码展示了这种异步模型,对于先前url数组的例子,就可以这样:

    listOfUrls.asyncEach(function(url, resume) {  
        $.get(url, function(response) {  
            // handle response  
            resume();  
        });  
    });  
    

    非常漂亮,不是吗。对于异步操作来说,上面代码是没有问题的,但如果其中某些操作是同步的,在resumeiterator这两个函数不停地互相调用可能会造成堆栈溢出,解决方法是用setTimeout来迭代:

    Array.prototype.asyncEach = function(iterator) {  
        var list = this,  
        n = list.length,  
        i = - 1;  
        var iterate = function() {  
            i += 1;  
            if (i === n) return;  
            iterator(list[i], resume);  
        };  
        var resume = function() {  
            setTimeout(iterate, 1);  
        };  
        resume();  
    };  
    

    setTimeout会把每次迭代操作的调用堆栈独立开,这样就不会溢出了。

     ps:虽然以上setTimeout的时间参数设为0毫秒,还会有10ms左右的延时,100次迭代就会造成1秒左右的延时,对一些苛刻要求时间的应用是一个浪费,解决方法是用setZeroTimeout代替setTimeout

    这是下一篇介绍的 setZeroTimeout

  • 相关阅读:
    12-29 批量删除
    12-29 注册审核
    12-25造数据库面向对象
    12-23 会话保持
    2016-12-19 php修改数据库数据
    12-18数据访问
    12-16php测试题
    1027 制作表格
    1027 超链接
    1027 HTML
  • 原文地址:https://www.cnblogs.com/aj3423/p/3150513.html
Copyright © 2020-2023  润新知