用Nodejs遍历云存储文件
起因
最近想要将云存储中的文件去重。因为有现成的Nodejs的API,所以打算用Nodejs实现此功能。
伪代码如下:
scanDir = function(uri){
return new Promise(function(resove, reject) {})
}
getFileInfo = function(uri){
return new Promise(function(resove, reject) {})
}
dealDir = aysnc function(uri) {
await scanDir(uri).then(function(res){
for (v of res) {
if (res.type === "Folder") {
dealDir(uri + '/' + v);
} else {
getFileInfo(uri + '/' + v).then(function(res){
//将文件信息存入数据库
})
}
}
}).catch(function(){})
}
递归什么的,用起来得心应手,在加上Promise这种大杀器,配合await用起来更是无人能挡。几百个文件的测试没问题,但真正运行起来之后,爆栈了。
分析
按道理讲,我只有3层目录,就算递归也不会有多少函数入栈。那么到底是什么原因呢?
因为Promise的递归容易出问题,比如上面的例子,虽然dealDir里面的scanDir函数被await了,但是dealDir函数本身还是压在栈里,并没有阻塞运行。
这样一层层地dealDir压入栈,迟迟等不到scanDir函数回调的响应导致了最终的爆栈。
如图:

解决方法
最后我选择了一种相对安全的方式:避免递归,用队列处理。
伪代码如下:
scanDir = function(uri){
return new Promise(function(resove, reject) {})
}
getFileInfo = function(uri){
return new Promise(function(resove, reject) {})
}
dealDir = aysnc function(uri) {
let folders = []
folders.push(uri)
while (folders.lenth > 0) {
let tmpfolder = folders.shift();
await scanDir(tmpfolder).then(function(res){
for (v of res) {
if (res.type === "Folder") {
folders.push(tmpfolder + '/' + v);
} else {
getFileInfo(tmpfolder + '/' + v).then(function(res){
//将文件信息存入数据库
})
}
}
}).catch(function(){})
}
}
参考资料
了解JavaScript的工作原理可以参考:
美团面试题:https://segmentfault.com/a/1190000015057278
JavaScript是如何工作的:
https://github.com/xitu/gold-miner/blob/master/TODO/how-javascript-works-event-loop-and-the-rise-of-async-programming-5-ways-to-better-coding-with.md
用Nodejs遍历云存储文件的更多相关文章
- DLNA架构在机顶盒上播放云存储文件的实现
DLNA 架构在机顶盒上播放云存储文件的实现 摘要: 随着越来越多的数码设备,音像设备等对 UPNP 协议的支持和普及,业界对多媒体内容提供服务的需求越越来越强烈,为了实现遵循 UPNP 协议和 ...
- NodeJS遍历文件生产文件列表
本文实例讲述了NodeJS遍历文件生产文件列表功能.分享给大家供大家参考,具体如下: 功能需求:在工作中我们可能经常需要知道项目中静态文件列表发布,一个一个去检索写,那就太苦逼了. 要想知道里面的文件 ...
- nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG
需求描述,由于工作的需要,需要将原本用于1280 720的网页改为1920 1080的网页(电视端页面).需求可以拆分为两部分,代码部分的修改以及图片的修改.在代码部分,需要将所有位置以及大小相关的值 ...
- nodejs:遍历文件夹文件统计文件大小
根据 http://blog.csdn.net/hero82748274/article/details/45700465这里的思路对读写文件做了一个 封装: webpack在打包的时候可以借助ass ...
- nodejs 遍历数组的两种方法
var array = [1,2,3]; array.forEach(function(v,i,a){ console.log(v); console.log(i); console.log(a); ...
- 初入 nodejs -遍历文件夹
//操作文件 /* 1.fs.stat 获取文件状态 2.fs.readdir 读取文件夹数据 3.fs.access 判断文件夹是否存在 4.path.join 拼路径 */ //操作文件 cons ...
- nodejs 遍历文件夹下所有的图片改名为中文
安装依赖 $ npm init -y && npm i fs-extra globby request -S main.js const fs = require('node-fs-e ...
- NodeJs 遍历文件夹内容 上传到服务器.并输出上传记录文件
var path = require('path'); var glob = require('glob') var fs = require('fs'); var Promise = require ...
- nodejs 遍历目录
1 var fs = require("fs"), path = require("path"); function walk(dir, callback) { ...
随机推荐
- NodeJS模块和ES6模块系统语法及注意点
社区模块规范: 1.CommonJS规范 规范实现者: NodeJS 服务端 Browserify 浏览器 2.AMD规范 全称 异步模块定义 规范实现者: RequireJS 浏览器 3.CMD规范 ...
- 20165230田坤烨网络对抗免考报告_Windows系统提权
目录 KERNEL EXPLOITATION 服务攻击: DLL劫持 攻击 不安全的服务权限 探测 unquoted path未被引号标记的路径 探测 攻击 服务注册表键 探测 攻击 Named Pi ...
- python虚拟环境切换无效问题
使用pycharm创建新项目,使用虚拟环境,但是进入到项目的cainiao_guoguo_health\venv\Scripts目录启动虚拟环境后,安装第三方库,却还是安装到其他环境中去了, 检查ac ...
- IntelliJ IDEA编辑器的使用技巧
目录 1. 使用技巧 1. 跳转小工具 2. 无处不在的跳转 3. 精准搜索 4. 列操作: 5. live template 6. postfix 7. ALT+ENTER智能提示,代码优化 8. ...
- 透彻的掌握 Spring 中@transactional 的使用
事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编码式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...
- cad.net 图元延迟显示,动画效果,编辑器延迟发送提示.
public class Command_test { [CommandMethod("tt", CommandFlags.Modal | CommandFlags.UsePick ...
- 在flask中使用sqlalchemy插入数据返回新增的id
user = User(‘name’=‘张三’)db.session.add(user)db.session.flush()#输出新插入数据的主键print(user.id)#此时数据才插入到数据库中 ...
- [转帖]Kubesphere all-in-one 安装方式.
All-in-One 模式 对于首次接触 KubeSphere 高级版的用户,想寻找一个最快安装和体验 KubeSphere 高级版核心功能的方式,all-in-one 模式支持一键安装 KubeSp ...
- Apache Kafka - How to Load Test with JMeter
In this article, we are going to look at how to load test Apache Kafka, a distributed streaming plat ...
- STM8L独立看门狗IWDG
简单扼要 void IWDG_Init(void)//初始化 { IWDG->KR = 0xcc;//启动IWDG IWDG->KR = 0x55;//解除PR及RLR的写保护 IWDG- ...