问题
everyone
I am working on some sort of image view application using node-webkit. I made a function to read dir inside the given location and search for the image files(*.jpg and *.png). Code I used is as follows:
app.js
var fs = require("fs");
var gui = require('nw.gui');
var win = gui.Window.get();
var directory;
var db = require('diskdb');
var path = require('path')
db = db.connect("lib/collections", ['temp']);
function chooseFile(name) {
var chooser = $(name);
scr = 0;
chooser.change(function(evt) {
directory = $(this).val();
var asdf;
console.clear();
readDir(directory);
$(this).val('').hide();
});
}
function readDir(directory){
c = 0;
console.log("reading "+directory);
if(fs.statSync(directory).isDirectory() == true){
fs.readdir(directory,function(err,files){
if (err){
console.log(err);
return;
}
var ext;
files.forEach(function(file){
console.log("Got what: "+file);
var fulls = directory+"\\"+file;
if(file.indexOf(".") != 0){
if(path.extname(fulls) == ""){
console.log("Got a directory: "+file);
if(fs.statSync(fulls).isDirectory() == true){
readDir(fulls);
}
}
else{
console.log("Got a file: "+file);
if(checkExtension(file, 'jpg,png')){
scr++;
c = saveTemp(fulls,scr,file);
}
}
}
});
if(c == 1){
loadgun();
}
});
}
}
function loadgun(){
if(db.temp.count()!=0){
for(i=1;i<=db.temp.count();i++){
var asd = db.temp.findOne({'id':i});
var theTempScript = $("#tmpl-imgholder").html();
var theTemp = Handlebars.compile(theTempScript);
$("#ContentWrapper").append(theTemp({"fulls":asd.file, "id":asd.id, "title":asd.title}));
}
}
}
saveTemp = function(file,id, title) {
var savedUser = db.temp.save({
file:file,
id:id,
title:title
});
return 1;
};
function checkExtension(str, ext) {
extArray = ext.split(',');
for(i=0; i < extArray.length; i++) {
if(str.toLowerCase().split('.').pop() == extArray[i]) {
return true;
}
}
return false;
};
$(document).ready(function(){
if(db.temp.count() != 0){
loadgun();
}
else{
$('#blah').css('display','block');
chooseFile('#blah');
}
});
index.html
<html>
.
.
.
<body>
<input type="file" nwdirectory id="blah" style="display:none"/>
<script src="js/jquery.min.js"></script>
<script src="js/app.js"></script>
<script src="js/handlebars.js"></script>
<script id="tmpl-imgholder" type="x-handlebars-template">
<div class="image-container grid__item" data-id="{{id}}" data-src="{{fulls}}">
<div class="cover" style="background:url({{fulls}})" title="{{title}}"></div>
<div class="info">
<div class="title">{{title}}</div>
</div>
<div class="clear"></div>
</div>
</script>
</body>
</html>
Here i tried to load data using loadgun function. Its hangs the node webkit window. If I could know when the readDir function terminates then i could do load the required datas. If there is another way please do say. Thanks in advance.
回答1:
the problem with readDir is that is asynchronous function , that is why you have to provide a callback. you can however use fs.readdirSync(path) which is synchronous , and then the code flows synchronously. a psoducode may look like this :
function readDirAsynch(dir){
var files = fs.readdirSync(dir);
for (var i in files){
if (files[i] isDir){
readDirAsynch(files[i]);
} else if (myCondition){
//do somehting
}
}
}
needless to say , you know that the function is done when the next line after the function call is being executed
回答2:
Quick answer: You can use the synchrohous method fs.readdirSync(path) and everything should work just fine for you. You don't need to keep reading. https://nodejs.org/api/fs.html#fs_fs_readdirsync_path
My personal suggestion:
Since node is single threaded I would recommend you to keep using the asynchronous version but adding a callback to your method.
This means that your "readDir" method is going to be asynchronous too. You only need to add a callback parameter to your method. E.g.
readDir(dir, fnCallback) {
...
fs.readdir(directory, function(err,files){
... doing cool stuff ...
fnCallback();
});
}
If you want to read more about writing asynchronous code maybe this guide can help you. http://callbackhell.com/
Also if you want to go further in the wonderful asynchronous world you can take a look to 'Promises' https://www.npmjs.com/package/node-promise, 'Future' https://www.npmjs.com/package/async-future, 'Async' https://www.npmjs.com/package/async and have more fun than you have ever imagined before.
来源:https://stackoverflow.com/questions/29149553/how-to-find-out-if-reading-dir-is-completed