Tai Tran
Tai Tran

Reputation: 1404

Async in getting files in folder?

I am new in Node.js . All I did in here is get file list in folder... Everything in Node.js seem to async but my function I want it in synchronous way. So, I do as follow.

function getFiles() {
var file = [];
var walker = walk.walk('./files');

walker.on('file', function (root, stat, next) {
    file.push(root + '/' + stat.name);
    next();
})

walker.on('end', function () {
    console.log(JSON.stringify(file));
})

return file;}

It worked as I expected :

["./files/1.mp3","./files/2.mp3","./files/3.mp3","./files/4.mp3","./files/5.mp3","./files/6.mp3","./files/7.mp3","./files/8.mp3"]

but when I assigned that function to variable

var list = getFiles();
 response.writeHead(200, {'Content-type':'application/json'});
response.end(JSON.stringify(list));

It always returned nothing, I think that getFiles() run in another thread so can not receive value of data. Thank for your reading.

Upvotes: 1

Views: 425

Answers (2)

Paul
Paul

Reputation: 27433

  • Async functions return before they are ready
  • You can't return data thats not there in your own code
  • Async functions often take a callback argument that is executed when they are ready
  • You own code could ask for its own callbacks

`

function getFiles(callBack) {
var file = [];
var walker = walk.walk('./files');

walker.on('file', function (root, stat, next) {
    file.push(root + '/' + stat.name);
    next();
})

walker.on('end', function () {
    console.log(JSON.stringify(file));
    callBack(file);
})

}

// assuming server environment, express, connect, etc...

app.get('/list', function(req, res){
      getFiles(function(D){ res.json(D) });
});

`

Upvotes: 1

Gabriel
Gabriel

Reputation: 18780

I can shed some light on the behavior you are experiencing by outlining the flow of the application as it is run:

call to getFiles
  declare files array and walker
  bind walker event "file" and "end" to callbacks
  return files array

walker file event fires
walker end event fires

as you can see the events are firing out of band with the method call. To deal with this the common node.js approach is to setup your code something like the following:

function getFiles(callback) {
  var file = [];
  var walker = walk.walk('./files');

  walker.on('file', function (root, stat, next) {
    file.push(root + '/' + stat.name);
    next();
  })

  walker.on('end', function () {
    callback(file);
  })
}

now when you go to execute this method you would do something like this:

getFiles(function(list){
  response.writeHead(200, {'Content-type':'application/json'});
  response.end(JSON.stringify(list));
});

obviously this is a little unsightly since the controller now has to create a callback scenario and the getFiles method need to execute that callback in course. Another approach is to use the Promises concept, which I will leave to the discovery of the reader with the following link: https://github.com/kriskowal/q

Upvotes: 2

Related Questions