首先通过一个问题的出现以及解决,来介绍cc.AsyncPool的实现。
       假设现在有个需求,就是一个页面里面要显示很多图片,而且这些图片是需要下载的。如果我们的实现方法是显示这个页面的时候,一次性请求并创建这些图片,这样做可能会出现当我们要显示这个页面的时候,会出现卡了几秒,然后图片一次性显示出来,显然这种体验是很差的。所以我们可能优化一下,当要显示这个页面时候先显示背景,然后创建去请求一个图片并创建成功后再去处理下一个。这里的实现模式就用cc.AsyncPool异步池来实现。
       通过上面的问题,我们先思考一下,我们实现的功能就是,别人传一堆数据过来,我们先取出一个数据,然后交给迭代器且处理,同时迭代器在处理完成的时候通知给我们,在通知给我们的时候,我们继续去下一个数据,当迭代器处理完成的数据等于原先总的数据的时候,就说明处理完成了。

所以我们实现一个异步池需要一下参数
      1、迭代处理的对象srcObj(上面例子的所有图片的远程地址列表)
      2、并行限制 limit,就是一次可以同时处理数量
      3、迭代器(上面例子的单个图片下载和创建控件流程)
      4、全部处理后的回调 onEnd
      5、上下文target(js的语法,修改函数的this指向)

下面是cc.AsyncPool带注释的代码。

//+++++++++++++++++++++++++something about async begin+++++++++++++++++++++++++++++++
/*** Async Pool class, a helper of cc.async* @param {Object|Array} srcObj 迭代对象* @param {Number} limit the limit of parallel(并行) number  并行限制* @param {function} iterator 迭代器* @param {function} onEnd 全部执行后的回调* @param {object} target 迭代的上下文* @constructor*/
// async 异步
// 异步池大概流程:
// 记录总的需要处理的数量
// 取出一个数据,当前工作的数量加1,并执行迭代器
//迭代器执行结束后,当前工作的数量减1,已完成的数据加1
// 如果已完成的数量等于需要处理的数据,表明全部处理完成,反之表面还没全部处理结束,尝试处理下一个数据
// 处理下一个数据时,如果当前工作的数据没有超过最大并发数,且待处理的池还有数据,取下个数据处理cc.AsyncPool = function (srcObj, limit, iterator, onEnd, target) {var self = this;// 是否执行后全部结束的回调self._finished = false;// 需要处理的数据self._srcObj = srcObj;// 同时并发的最大数量self._limit = limit;// 等待处理的数据池self._pool = [];self._iterator = iterator;self._iteratorTarget = target;self._onEnd = onEnd;self._onEndTarget = target;self._results = srcObj instanceof Array ? [] : {};self._errors = srcObj instanceof Array ? [] : {};// 把srcObj已index-value的元素压入到数组_poolcc.each(srcObj, function (value, index) {self._pool.push({index: index, value: value});});// 总的数量self.size = self._pool.length;// 已经处理完成的数量,用于处理一个结束后判断是否全部处理完成用self.finishedSize = 0;// 正在工作的数量self._workingSize = 0;self._limit = self._limit || self.size;// 注入迭代器和其上下文self.onIterator = function (iterator, target) {self._iterator = iterator;self._iteratorTarget = target;};// 注入结束回调和其上下文(这个是不是没有用,和下面的onEnd冲突?)self.onEnd = function (endCb, endCbTarget) {self._onEnd = endCb;self._onEndTarget = endCbTarget;};// 处理单个self._handleItem = function () {var self = this;// 待处理池为空或者 当前工作的数量已经达到限制if (self._pool.length === 0 || self._workingSize >= self._limit)return;                                                         // 移除出一个var item = self._pool.shift();var value = item.value, index = item.index;// 正在处理的数量加1self._workingSize++;// 运行迭代器,参数为value,key,单个回调函数,异步池对象self._iterator.call(self._iteratorTarget, value, index,// 单个处理接口回调函数,参数为err和接口function (err, result) {// 结束回调已经执行过if (self._finished) {return;}// 记录每个数据处理的错误或者结果if (err) {self._errors[this.index] = err;}else {self._results[this.index] = result;}// 已完成数量加1self.finishedSize++;// 正在运行数量减1self._workingSize--;// 完成数量等于总的数量(这里可以去掉这个变量)// 可以用当前正在工作的为空,且异步池没有对象了// if (self._workingSize === 0 && self._pool.length === 0)if (self.finishedSize === self.size) {var errors = self._errors.length === 0 ? null : self._errors;self.onEnd(errors, self._results);return;}// 处理完一个后,处理下一个self._handleItem();}.bind(item),self);};// 异步池创建成功后,调用这个开始处理数据self.flow = function () {var self = this;if (self._pool.length === 0) {if (self._onEnd)self._onEnd.call(self._onEndTarget, null, []);return;}// 一次性并行多个for (var i = 0; i < self._limit; i++)self._handleItem();};// 全部处理完成回调self.onEnd = function(errors, results) {self._finished = true;if (self._onEnd) {var selector = self._onEnd;var target = self._onEndTarget;// 清空引用self._onEnd = null;self._onEndTarget = null;selector.call(target, errors, results);}};
};

cocos2dx-js CCBoot.js异步池cc.AsyncPool浅析相关推荐

  1. MySQL会回收使用中的连接吗_Node.js实现mysql连接池使用事务自动回收连接的方法示例...

    本文实例讲述了Node.js实现mysql连接池使用事务自动回收连接的方法.分享给大家供大家参考,具体如下: var mysql = require('mysql'), Connection = re ...

  2. 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?

    https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...

  3. 简单了解Vue的异步请求,axios-0.18.0.js插件实现异步

    Vue的异步请求 Vue 异步操作 在 Vue 中发送异步请求,本质上还是 AJAX.我们可以使用 axios 这个插件来简化操作! 使用步骤 引入 axios 核心 js 文件. 调用 axios ...

  4. node mysql 连接池创建_Node.js使用MySQL连接池的方法实例

    本文实例讲述了Node.js使用MysqL连接池的方法.分享给大家供大家参考,具体如下: Nodejs如何使用MysqL Nodejs要连接MysqL,可以使用Nodejs的MysqL驱动来实现.比如 ...

  5. JS中的异步任务有哪些

    JS中的异步任务有哪些 异步任务指的是,不进入主线程.而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请 ...

  6. js中的异步与同步,解决由异步引起的问题

    js中的异步与同步,解决由异步引起的问题 参考文章: (1)js中的异步与同步,解决由异步引起的问题 (2)https://www.cnblogs.com/zhuchenglin/p/7651990. ...

  7. js中的异步[Important]

    js作为前端最主流的语言,主要处理页面显示变化(mutation)和异步(asynchronicity), js语言的基本要素和使用惯例的演化大都围绕着这两大主题,两者均值得总结和思考的主题, 这里先 ...

  8. js延迟(异步)加载的6种方式 为什么要延迟加载js呢?

    对于js的优化(关于js的延迟加载)的好处是有助于提高页面加载速度,js延迟加载就是等页面加载完成之后在加载js文件.    之所以要优化是因为HTML元素是按其在页面中出现的次序调用的,如果用jav ...

  9. 话说js中的异步编程。

    转载自品略图书馆 http://www.pinlue.com/article/2020/07/0412/3110968788347.html JS异步编程模型 在理解js异步编程时, 我们先再心中想一 ...

最新文章

  1. [git/svn]Git和SVN差异
  2. 设计模式-2-代理模式
  3. Java基础:多线程
  4. 《黑天鹅》读书笔记(part3)--那些声称注重过程而非结果的人并没有完全讲真话
  5. python怎么安装bokeh_python怎么安装bokeh
  6. Visual Studio Code使用问题
  7. tensorflow2.0及以上版本在使用Session模块时报错:AttributeError: module ‘tensorflow‘ has no attribute ‘Session‘ 已解决
  8. intel编译器_试试吧!用 Go 写一个即时编译器(JIT)
  9. javaScript从入门到精通3.md
  10. android x866.0 教程,海尔暴风AmlogicT866平台升级步骤教程
  11. C++程序设计课程主页-2014级
  12. Fiddler+夜神模拟器+xposed+justTrustMe手机抖音抓包
  13. 宇宙简史——星光中有什么秘密?
  14. 数据采集系统有哪几种采集方式?
  15. VSCode前端开发工具插件--LiveServer实时刷新网页
  16. GPU驱动及CUDA安装流程介绍
  17. C++--【基础】--HEX、DEC、OCT数据转换
  18. 【自学笔记】尚硅谷数据结构与算法Chapter 5 递归
  19. 仿QQ浏览器mac版官网主页 html css3特效
  20. 今日头条安卓_我为什么开始对今日头条和抖音反感了

热门文章

  1. 计算机科学与技术考研考英语几,计算机科学与技术考研考哪些科目?
  2. Rocket MQ(二)消息详解
  3. 【消息队列】RocketMQ 基础知识扫盲
  4. xml的复杂解析取值和节点插入导出合并后的xml文件
  5. 【转载】女浴室起火之九个震撼的故事,不看一定会后悔
  6. 搭建一个页面并备份用户上传的文件项目作业
  7. word段落居中的快捷键_「Word快捷键大全」Word2016/2013/2010/2007常用快捷键大全
  8. WordPress独立后台壁纸小程序/WordPress壁纸小程序源码
  9. LTE笔记(二):OFDM在上行 / 下行链路中的应用
  10. Thinking In Java学习笔记