Node.js 如何利用异步提升任务处理速度


Posted in Javascript onJanuary 07, 2019

今天在做一个小任务,需要调用阿里云的图像识别接口,对 62662 张照片进行场景识别,并将结果写到本地的 csv 文件中。

因为任务很简单,没想很多就开始码。自从有了 async/await 之后,已经很久不写 callback 了,所以上手就写成这样:

本文所有代码均有简化,只保留关键过程

async fetchSceneTags(imagePath) {
  try {
   const result = await callAliyunAPI(imagePath);
   return result.errno === 0 ? result.tags : [];
 } catch(error) {
   return [];    
 }
}

async function writeScene(paths) {
  for (let i = 0, len = paths.length; i < len; i++) {
    await tags = fetchSceneTags(paths[i])
    writeToFile(tags);
    writeStdout(`${i} / ${len}`);
  }
}

function start() {
  const paths = loadPaths();
  writeScene(paths);
}

运行起来以后没问题就放着忙别的去了。过了差不多 2 小时回来一看,才跑了 17180 张图,每分钟 144 张。这才意识到同步速度太慢了,于是停掉进程,将代码改成下面这样:

fetchSceneTagsAsync(imagePath, callback) {
  callAliyunAPI(imagePath)
    .then(result => {
   const tags = result.errno === 0 ? result.tags : [];
     callback(tags);
   })
    .catch(error => callback([]));
}

function writeSceneAsync(paths) {
  const callback = tags => {
    await tags = fetchSceneTagsAsync(paths[i])
    writeToFile(tags);
  }
  
  paths.forEach(path => fetchSceneTagsAsync(path, callback));
}

function start() {
  const paths = loadPaths();
  writeSceneAsync(paths);
}

跑了一下,直接停摆了。嗯,不能一下把请求全发出去,加一个 Throttle:

fetchSceneTagsAsync(imagePath, callback) {
  callAliyunAPI(imagePath)
    .then(result => {
   const tags = result.errno === 0 ? result.tags : [];
     callback(tags);
   })
    .catch(error => callback([]));
}

function throttle(paths, callback) {
  if(paths.length === 0) return;
  
  const sub = paths.splice(0, 10);
  sub.forEach(path => fetchSceneTagsAsync(path, callback));
 setTimeout(() => throttle(paths, callback), 1000)
}

function writeSceneAsync(paths) {
  const callback = tags => {
    await tags = fetchSceneTagsAsync(paths[i])
    writeToFile(tags);
  }
  
  throttle(paths, callback)
}

function start() {
  const paths = loadPaths();
  writeSceneAsync(paths);
}

重新启动服务,观察了一下,大约每分钟处理 568 张图片,速度提升约 4 倍。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
Nov 05 Javascript
详解Javacript和AngularJS中的Promises
Feb 09 Javascript
原生javascript实现匀速运动动画效果
Feb 26 Javascript
js 定义对象数组(结合)多维数组方法
Jul 27 Javascript
BootStrap轻松实现微信页面开发代码分享
Oct 21 Javascript
使用 bootstrap modal遇到的问题小结
Nov 09 Javascript
基于jQuery的checkbox全选问题分析
Nov 18 Javascript
详解jquery和vue对比
Apr 16 jQuery
详解vue-cli中使用rem,vue自适应
May 06 Javascript
Vue组件间通信 Vuex的用法解析
Aug 05 Javascript
VUE实现强制渲染,强制更新
Oct 29 Javascript
javascript函数式编程基础
Sep 15 Javascript
vue封装一个简单的div框选时间的组件的方法
Jan 06 #Javascript
如何封装了一个vue移动端下拉加载下一页数据的组件
Jan 06 #Javascript
浅谈在Vue.js中如何实现时间转换指令
Jan 06 #Javascript
浅谈Vue.js中如何实现自定义下拉菜单指令
Jan 06 #Javascript
react-router4按需加载(踩坑填坑)
Jan 06 #Javascript
React 实现拖拽功能的示例代码
Jan 06 #Javascript
Next.js实现react服务器端渲染的方法示例
Jan 06 #Javascript
You might like
php版微信开发Token验证失败或请求URL超时问题的解决方法
2016/09/23 PHP
JavaScript window.setTimeout() 的详细用法
2009/11/04 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
网页源代码保护(禁止右键、复制、另存为、查看源文件)
2012/05/23 Javascript
js 获取屏幕各种宽高的方法(浏览器兼容)
2013/05/15 Javascript
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
JS弹出对话框实现方法(三种方式)
2015/12/18 Javascript
实例剖析AngularJS框架中数据的双向绑定运用
2016/03/04 Javascript
Bootstrap实现水平排列的表单
2016/07/04 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
2017/03/02 Javascript
Angular 4环境准备与Angular cli创建项目详解
2017/05/27 Javascript
React学习笔记之列表渲染示例详解
2017/08/22 Javascript
通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题
2018/04/08 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
2018/05/01 Javascript
nodejs 生成和导出 word的实例代码
2018/07/31 NodeJs
微信小程序模板template简单用法示例
2018/12/04 Javascript
layui-tree实现Ajax异步请求后动态添加节点的方法
2019/09/23 Javascript
详解vue页面首次加载缓慢原因及解决方案
2019/11/06 Javascript
python使用cStringIO实现临时内存文件访问的方法
2015/03/26 Python
Python设计模式中单例模式的实现及在Tornado中的应用
2016/03/02 Python
Python 结巴分词实现关键词抽取分析
2017/10/21 Python
python文件拆分与重组实例
2018/12/10 Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
2020/01/18 Python
matplotlib 对坐标的控制,加图例注释的操作
2020/04/17 Python
python中使用.py配置文件的方法详解
2020/11/23 Python
使用python tkinter开发一个爬取B站直播弹幕工具的实现代码
2021/02/07 Python
技术经理的自我评价范文
2013/12/03 职场文书
幼儿园中班教师寄语
2014/04/03 职场文书
《宿建德江》教学反思
2014/04/23 职场文书
党员民主生活会个人整改措施材料
2014/09/16 职场文书
计生办班子群众路线教育实践活动个人对照检查材料思想汇报
2014/10/04 职场文书
单位单身证明样本
2014/10/11 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
自我检讨书怎么写
2015/05/07 职场文书
为什么RedisCluster设计成16384个槽
2021/09/25 Redis
Netflix《海贼王》真人版剧集多张片场照曝光
2022/04/04 日漫