起因

最近想要将云存储中的文件去重。因为有现成的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. css规范思维导图(仅限于自己)

  2. C++2.0新特性(三)——<=default,=delete、alias(别名)、noexcept、override、final、以及和const对比>

    一.=default,=delete 1.首先我们要回顾一下类默认函数的概念: C++中,当我们设计与编写一个类时,若不显著申明,则类会默认为我们提供如下几个函数: (1)构造函数(A()).(2)析 ...

  3. Centos开发小计

    1. 生成静态库,linux下库的规则是lib开头 g++ -c code.cpp ar cr libcode.a code.o

  4. Java集合详解6:这次,从头到尾带你解读Java中的红黑树

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  5. SpringCloud组件学习-图

    图很清晰,直接放大浏览器,或者下载下来放大看

  6. Python【每日一问】27

    问: [基础题1]:将一个正整数分解质因数.例如:输入 90, 打印出 90=2*3*3*5 . [基础题2]:一个数如果恰好等于它的因子之和,这个数就称为“完数” .例如6=1+2+3.请找出 10 ...

  7. JavaSE 面试题: 成员变量与局部变量

    JavaSE 面试题 成员变量与局部变量 public class Test { static int s; int i; int j; { int i = 1; i++; j++; s++; } p ...

  8. java解析复杂的json字符串

    Java解析Json字符串--复杂对象(方法一)   { "name": "三班", "students": [ { "age&q ...

  9. Excel数据都在一列,如何批量转置

    Evernote Export Excel数据都在一列,如何批量转置 创建时间: 2019-10-21 星期一 13:41 作者: 苏苏 标签: excel, 转置       问题 Excel数据都 ...

  10. Java基础扫盲系列(-)—— String中的format

    Java基础扫盲系列(-)-- String中的format 以前大学学习C语言时,有函数printf,能够按照格式打印输出的内容.但是工作后使用Java,也没有遇到过格式打印的需求,今天遇到项目代码 ...