起因

最近想要将云存储中的文件去重。因为有现成的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. Django Flatpage设置

    参考链接:https://docs.djangoproject.com/en/1.11/ref/contrib/flatpages/ 知识点: 通过django.site数据库记录表,对应域名和请求站 ...

  2. js 将图片转换为 base64

    var img = document.getElementById('s_lg_img'); function getBase64Image(img) { var canvas = document. ...

  3. 基于web公交查询系统---站点信息管理

    界面设计: 界面设计代码获取: 搭建好框架获取信息: 核心代码: var users = [ ];//获取到的bus所有站点信息 var rowIndex = -1; $.ajax({ url: &q ...

  4. 使用docker部署nginx+tomcat架构(3):使用docker-compose简化部署操作

    经历了之前的两篇,我们已经大体上了解了docker部署容器的过程. 使用docker部署nginx+tomcat架构 使用docker部署nginx+tomcat架构():访问mysql数据库 不过, ...

  5. Oracle 'no privileges on tablespace 表空间名称' 问题解决

    create user bryan identified by bryan;   grant create session to bryan;   grant create table to brya ...

  6. SpringBoot+Mysql 无法保存emoj表情?

    尤记得很久以前,想存 emoj 表情到 mysql 中,需要额外的将 emoj 表情转码之后保存,每次读取时,再解码还原成一下:每次这种 sb 的操作,真心感觉心塞,那么有没有办法直接存呢? mysq ...

  7. php form表单ajax上传图片方法

    form表单ajax上传图片方法 先引用jquery.form.js 前台代码<pre><form id="form1"> <input id=&qu ...

  8. MySQL 索引小结

    1.!=.not in 在primary key上使用 !=.not in,explain 的 type 是 range,非primary key是全表扫描(即非主键字段即使有索引也无法应用) 2.a ...

  9. VUE后缀页面调试

    在VUE中Js代码可以直接设置断点进行调试,但是vue文件中点击断点无反应,可以在想要断点的地方增加一行代码即可   debugger

  10. C#怎么判断字符是不是汉字 汉字和Unicode编码互相转换

    判断一个字符是不是汉字通常有三种方法,第1种用 ASCII 码判断(在 ASCII码表中,英文的范围是0-127,而汉字则是大于127,根据这个范围可以判断),第2种用汉字的 UNICODE 编码范围 ...