zoukankan      html  css  js  c++  java
  • 用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

  • 相关阅读:
    jchdl
    jchdl
    jchdl
    jchdl
    jchdl
    jchdl
    jchdl
    UVa 437 (变形的LIS) The Tower of Babylon
    UVa 1025 (动态规划) A Spy in the Metro
    UVa 10129 (并查集 + 欧拉路径) Play on Words
  • 原文地址:https://www.cnblogs.com/bugutian/p/11244369.html
Copyright © 2011-2022 走看看