起因

最近想要将云存储中的文件去重。因为有现成的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遍历云存储文件的更多相关文章

  1. DLNA架构在机顶盒上播放云存储文件的实现

    DLNA 架构在机顶盒上播放云存储文件的实现   摘要: 随着越来越多的数码设备,音像设备等对 UPNP 协议的支持和普及,业界对多媒体内容提供服务的需求越越来越强烈,为了实现遵循 UPNP 协议和  ...

  2. NodeJS遍历文件生产文件列表

    本文实例讲述了NodeJS遍历文件生产文件列表功能.分享给大家供大家参考,具体如下: 功能需求:在工作中我们可能经常需要知道项目中静态文件列表发布,一个一个去检索写,那就太苦逼了. 要想知道里面的文件 ...

  3. nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG

    需求描述,由于工作的需要,需要将原本用于1280 720的网页改为1920 1080的网页(电视端页面).需求可以拆分为两部分,代码部分的修改以及图片的修改.在代码部分,需要将所有位置以及大小相关的值 ...

  4. nodejs:遍历文件夹文件统计文件大小

    根据 http://blog.csdn.net/hero82748274/article/details/45700465这里的思路对读写文件做了一个 封装: webpack在打包的时候可以借助ass ...

  5. nodejs 遍历数组的两种方法

    var array = [1,2,3]; array.forEach(function(v,i,a){ console.log(v); console.log(i); console.log(a); ...

  6. 初入 nodejs -遍历文件夹

    //操作文件 /* 1.fs.stat 获取文件状态 2.fs.readdir 读取文件夹数据 3.fs.access 判断文件夹是否存在 4.path.join 拼路径 */ //操作文件 cons ...

  7. nodejs 遍历文件夹下所有的图片改名为中文

    安装依赖 $ npm init -y && npm i fs-extra globby request -S main.js const fs = require('node-fs-e ...

  8. NodeJs 遍历文件夹内容 上传到服务器.并输出上传记录文件

    var path = require('path'); var glob = require('glob') var fs = require('fs'); var Promise = require ...

  9. nodejs 遍历目录

    1 var fs = require("fs"), path = require("path"); function walk(dir, callback) { ...

随机推荐

  1. ESA2GJK1DH1K基础篇: Android连接MQTT简单的Demo

    题外话 我老爸也问我物联网发展的趋势是什么!!!!!! 我自己感觉的:(正在朝着 "我,机器人" 这部电影的服务器方向发展) 以后的设备都会和服务器交互,就是说本地不再做处理,全部 ...

  2. NOIP2019翻车前计划以及日记

    目前只有日记和草拟计划(Sua机洗点~),等停课后会实施计划,试行期为一天. 根据试行期的学习效果制定计划. update 1:试行期结束,完全可以按计划来. update 2:计划暂时变更,以适应我 ...

  3. Docker入门笔记(Centos7)

    centos7 wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo vim docker-c ...

  4. iptables 常用处理动作

    在iptables中,-j 参数用来指定要进行的处理动作,常用的处理动作包括:ACCEPT.REJECT.DROP.REDIRECT.MASQUERADE.LOG.DNAT.SNAT.MIRROR.Q ...

  5. xsxs

    import subprocess compilePopen = subprocess.Popen('gcc haha',shell=True,stderr=subprocess.PIPE) comp ...

  6. Hbase安装使用

    启动Hadoop 启动Hbase jps 进入shell 建立表及使用

  7. 华为鸿蒙OS发布!方舟支持混合编译,终将可替换安卓?

    前言 有关于鸿蒙的消息之前也有说过,就在昨天下午,华为举行了2019开发大会,正式推出了鸿蒙os系统(Harmony).其相关负责人表示,也是基于微软内核的全场景分布式OS   鸿蒙凭借微内核的优势, ...

  8. react + node + express + ant + mongodb 的简洁兼时尚的博客网站

    前言 此项目是用于构建博客网站的,由三部分组成,包含前台展示.管理后台和后端. 此项目是基于 react + node + express + ant + mongodb 的,项目已经开源,项目地址在 ...

  9. Spring Boot进阶系列三

    Thymeleaf是官方推荐的显示引擎,这篇文章主要介绍怎么让spring boot整合Thymeleaf.  它是一个适用于Web和独立环境的现代服务器端Java模板引擎. Thymeleaf的主要 ...

  10. websocket通信1009错误,

    问题说明: springboot继承 WebSocketConfigurer实现websocket通信服务,服务器端报错,"The decoded text message was too ...