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 相关文章推荐
Web开发者必备的12款超赞jQuery插件
Dec 03 Javascript
dojo学习第二天 ajax异步请求之绑定列表
Aug 29 Javascript
javascript学习笔记(十九) 节点的操作实现代码
Jun 20 Javascript
checkbox选中与未选中判断示例
Aug 04 Javascript
原生js实现数字字母混合验证码的简单实例
Dec 10 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
Dec 13 Javascript
ReactNative短信验证码倒计时控件的实现代码
Jul 20 Javascript
解决js ajax同步请求造成浏览器假死的问题
Jan 18 Javascript
AngularJS监听ng-repeat渲染完成的方法
Mar 20 Javascript
详解Vue SPA项目优化小记
Jul 03 Javascript
jquery选择器和属性对象的操作实例分析
Jan 10 jQuery
jQuery使用ajax传递json对象到服务端及contentType的用法示例
Mar 12 jQuery
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强制下载类型的实现代码
2011/04/21 PHP
PHP中的strtr函数使用介绍(str_replace)
2011/10/20 PHP
php查询相似度最高的字符串的方法
2015/03/12 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
一个js的tab切换效果代码[代码分离]
2010/04/11 Javascript
Prototype源码浅析 String部分(二)
2012/01/16 Javascript
js屏蔽鼠标键盘(右键/Ctrl+N/Shift+F10/F11/F5刷新/退格键)
2013/01/24 Javascript
E3 tree 1.6在Firefox下显示问题的修复方法
2013/01/30 Javascript
javascript 对象数组根据对象object key的值排序
2015/03/09 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
浅谈JQ中mouseover和mouseenter的区别
2016/09/13 Javascript
详解利用exif.js解决ios手机上传竖拍照片旋转90度问题
2016/11/04 Javascript
自己封装的一个原生JS拖动方法(推荐)
2016/11/22 Javascript
js实现弹窗暗层效果
2017/01/16 Javascript
JavaScript实现简单的四则运算计算器完整实例
2017/04/28 Javascript
JavaScript实现鼠标滚轮控制页面图片切换功能示例
2017/10/14 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
原生js+cookie实现购物车功能的方法分析
2017/12/21 Javascript
利用vue.js实现被选中状态的改变方法
2018/02/08 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
2018/09/12 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
对vue v-if v-else-if v-else 的简单使用详解
2018/09/29 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
王纯业的Python学习笔记 下载
2007/02/10 Python
python网络编程学习笔记(四):域名系统
2014/06/09 Python
Python中模块与包有相同名字的处理方法
2017/05/05 Python
使用Turtle画正螺旋线的方法
2017/09/22 Python
详解python eval函数的妙用
2017/11/16 Python
Python 访问限制 private public的详细介绍
2018/10/16 Python
Python动态语言与鸭子类型详解
2019/07/01 Python
pygame实现打字游戏
2021/02/19 Python
python数值基础知识浅析
2019/11/19 Python
Anconda环境下Vscode安装Python的方法详解
2020/03/29 Python
python实现邮件循环自动发件功能
2020/09/11 Python
第一范式(1NF)、第二范式(2NF)和第三范式(3NF)之间的区别是什么?
2016/04/28 面试题
初中学校军训方案
2014/05/09 职场文书