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 相关文章推荐
在firefox和Chrome下关闭浏览器窗口无效的解决方法
Jan 16 Javascript
javascript将浮点数转换成整数的三个方法
Jun 23 Javascript
js闭包所用的场合以及优缺点分析
Jun 22 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
Jul 27 Javascript
jQuery动态星级评分效果实现方法
Aug 06 Javascript
详解JavaScript中this关键字的用法
May 26 Javascript
使用Script元素发送JSONP请求的方法
Jun 12 Javascript
原生js实现简单的模态框示例
Sep 08 Javascript
原生JS实现轮播图效果
Oct 12 Javascript
iview在vue-cli3如何按需加载的方法
Oct 31 Javascript
bootstrap datepicker的基本使用教程
Jul 09 Javascript
JavaScript中条件语句的优化技巧总结
Dec 04 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在字符串中查找另一个字符串
2008/11/19 PHP
php获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
php遍历类中包含的所有元素的方法
2015/05/12 PHP
JS backgroundImage控制
2009/05/19 Javascript
JQuery设置文本框和密码框得到焦点时的样式
2013/08/30 Javascript
js单例模式的两种方案
2013/10/22 Javascript
客户端js性能优化小技巧整理
2013/11/05 Javascript
5分钟理解JavaScript中this用法分享
2013/11/09 Javascript
Javascript 实现复制(Copy)动作方法大全
2014/06/20 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
2014/07/17 Javascript
js仿苹果iwatch外观的计时器代码分享
2015/08/26 Javascript
jQuery中的通配符选择器使用总结
2016/05/30 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
JS+HTML5 FileReader实现文件上传前本地预览功能
2020/03/27 Javascript
基于Vue2.X的路由和钩子函数详解
2018/02/09 Javascript
JavaScript设计模式之工厂模式简单实例教程
2018/07/03 Javascript
详解JavaScript中的坐标和距离
2019/05/27 Javascript
在Vue mounted方法中使用data变量详解
2019/11/05 Javascript
[01:01:18]VP vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python中Collection的使用小技巧
2014/08/18 Python
Python复制目录结构脚本代码分享
2015/03/06 Python
使用C#配合ArcGIS Engine进行地理信息系统开发
2016/02/19 Python
在python 不同时区之间的差值与转换方法
2019/01/14 Python
python读写csv文件实例代码
2019/07/05 Python
使用css3匹配手机屏幕横竖状态
2014/01/27 HTML / CSS
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
英国羊皮鞋类领先品牌:Just Sheepskin
2019/12/12 全球购物
牵手50台湾:专为黄金岁月的单身人士而设的交友网站
2021/02/18 全球购物
物业管理个人自我评价
2013/11/08 职场文书
文员的职业生涯规划发展方向
2014/02/08 职场文书
高中生的自我评价
2014/03/04 职场文书
2015年青年教师工作总结
2015/05/25 职场文书
2016优秀护士求职自荐信
2016/01/28 职场文书
JavaScript中document.activeELement焦点元素介绍
2021/11/27 Javascript
Django框架中模型的用法
2022/06/10 Python