zoukankan      html  css  js  c++  java
  • 异步&分段处理海量数据

    有一种并发合作方式,称为并发协作(cooperative concurrency)。这里的重点不再是通过
    共享作用域中的值进行交互(尽管显然这也是允许的!)。这里的目标是取到一个长期运
    行的“进程”,并将其分割成多个步骤或多批任务,使得其他并发“进程”有机会将自己
    的运算插入到事件循环队列中交替运行。
    举例来说,考虑一个需要遍历很长的结果列表进行值转换的 Ajax 响应处理函数。我们会
    使用 Array#map(..) 让代码更简洁:

    var res = [];
    // response(..)从Ajax调用中取得结果数组
    function response(data) {
    // 添加到已有的res数组
    res = res.concat(
    // 创建一个新的变换数组把所有data值加倍
    data.map( function(val){
    return val * 2;
    } )
    );
    }
    // ajax(..)是某个库中提供的某个Ajax函数
    ajax( "http://some.url.1", response );
    ajax( "http://some.url.2", response );


    如果 "http://some.url.1" 首先取得结果,那么整个列表会立刻映射到 res 中。如果记录
    有几千条或更少,这不算什么。但是如果有像 1000 万条记录的话,就可能需要运行相当
    一段时间了(在高性能笔记本上需要几秒钟,在移动设备上需要更长时间,等等)。
    这样的“进程”运行时,页面上的其他代码都不能运行,包括不能有其他的 response(..)
    调用或 UI 刷新,甚至是像滚动、输入、按钮点击这样的用户事件。这是相当痛苦的。
    所以,要创建一个协作性更强更友好且不会霸占事件循环队列的并发系统,你可以异步地
    批处理这些结果。每次处理之后返回事件循环,让其他等待事件有机会运行。
    这里给出一种非常简单的方法:

    var res = [];
    // response(..)从Ajax调用中取得结果数组
    function response(data) {
    // 一次处理1000个
    var chunk = data.splice( 0, 1000 );
    // 添加到已有的res组
    res = res.concat(
    // 创建一个新的数组把chunk中所有值加倍
    chunk.map( function(val){
    return val * 2;
    } )
    );
    // 还有剩下的需要处理吗?
    if (data.length > 0) {
    // 异步调度下一次批处理
    setTimeout( function(){
    response( data );
    }, 0 );
    }
    }
    // ajax(..)是某个库中提供的某个Ajax函数
    ajax( "http://some.url.1", response );
    ajax( "http://some.url.2", response );

    我们把数据集合放在最多包含 1000 条项目的块中。这样,我们就确保了“进程”运行时
    间会很短,即使这意味着需要更多的后续“进程”,因为事件循环队列的交替运行会提高
    站点 /App 的响应(性能)

    摘自《你不知道的javascript(中)》P155

  • 相关阅读:
    华为手机wifi调试adb,断开数据线offlin
    appium 识别抖音视频已经播放完成
    对于学习新知识的一点自我反思
    部分软件激活
    AndroidStudio 创建简单的app
    App 逆向思路
    链家
    pyqt5 截屏
    3.无重复字符的最长子串
    1.两数之和
  • 原文地址:https://www.cnblogs.com/LLLLily/p/10857545.html
Copyright © 2011-2022 走看看