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 相关文章推荐
javascript延时加载之defer测试
Dec 28 Javascript
原生js配合cookie制作保存路径的拖拽
Dec 29 Javascript
如何利用JS通过身份证号获取当事人的生日、年龄、性别
Jan 22 Javascript
jQuery 实现评论等级好评差评特效
May 06 Javascript
JavaScript浮点数及运算精度调整详解
Oct 21 Javascript
如何实现星星评价(jquery.raty.js插件)
Dec 21 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
Jan 19 Javascript
js鼠标跟随运动效果
Mar 11 Javascript
JS基于正则表达式的替换操作(replace)用法示例
Apr 28 Javascript
Nuxt.js踩坑总结分享
Jan 18 Javascript
详解vue后台系统登录态管理
Apr 02 Javascript
JavaScript 事件捕获冒泡与捕获详情
Nov 11 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 用数组降低程序的时间复杂度
2009/12/04 PHP
PHP采用XML-RPC构造Web Service实例教程
2014/07/16 PHP
CI(Codeigniter)的Setting增强配置类实例
2016/01/06 PHP
PHP的PDO操作简单示例
2016/03/30 PHP
TP5多入口设置实例讲解
2020/12/15 PHP
jquery下checked取值问题的解决方法
2012/08/09 Javascript
javascript动画浅析
2012/08/30 Javascript
JS 添加网页桌面快捷方式的代码详细整理
2012/12/27 Javascript
基于jQuery.Validate验证库知识点的详解
2013/04/26 Javascript
每天一篇javascript学习小结(Boolean对象)
2015/11/12 Javascript
javascript实现下拉提示选择框
2015/12/29 Javascript
浅析如何利用angular结合translate为项目实现国际化
2016/12/08 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
react 父组件与子组件之间的值传递的方法
2017/09/14 Javascript
vue axios 在页面切换时中断请求方法 ajax
2018/03/05 Javascript
JavaScript中.min.js和.js文件的区别讲解
2019/02/13 Javascript
js判断复选框是否选中的方法示例【基于jQuery】
2019/10/10 jQuery
Angular+Ionic使用queryParams实现跳转页传值的方法
2020/09/05 Javascript
Python http接口自动化测试框架实现方法示例
2018/12/06 Python
PyQt5根据控件Id获取控件对象的方法
2019/06/25 Python
python 绘制拟合曲线并加指定点标识的实现
2019/07/10 Python
Python列表去重复项的N种方法(实例代码)
2020/05/12 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
python 判断一组数据是否符合正态分布
2020/09/23 Python
AmazeUI 单选框和多选框的实现示例
2020/08/18 HTML / CSS
Lampegiganten丹麦:欧洲领先的照明网上商店
2018/04/25 全球购物
 Alo Yoga官网:购买瑜伽服装
2018/06/17 全球购物
阿迪达斯新加坡官方网站:adidas新加坡
2019/12/06 全球购物
个人授权委托书格式
2014/08/30 职场文书
退学证明范本3篇
2014/10/29 职场文书
会计实训报告范文
2014/11/04 职场文书
谢师宴答谢词
2015/01/05 职场文书
政府会议通知范文
2015/04/15 职场文书
Spring Boot配合PageHelper优化大表查询数据分页
2022/04/20 Java/Android
Python如何利用pandas读取csv数据并绘图
2022/07/07 Python