2

Alright, I need some help with generators in Node.

I really want to write code that looks like this:

require('./Class.js');
fs = require('fs');

var Directory = Class.extend({

    construct: function(path){
        this.path = path;
    },

    list: function*() {
        var files = [];

        yield fs.readdir(this.path, function(error, directoryFiles) {
            files = directoryFiles;
        });

        return files;
    },

});

var directory = new Directory('C:\\');
var list = directory.list();
console.log(list); // An array of files

Notes:

Is something like this possible?

Kirk Ouimet
  • 27,280
  • 43
  • 127
  • 177
  • That's not how asynchrony works with generators. – Bergi Mar 17 '14 at 20:41
  • possible duplicate of [How to wrap async function calls into a sync function in Node.js or Javascript?](http://stackoverflow.com/questions/21819858/how-to-wrap-async-function-calls-into-a-sync-function-in-node-js-or-javascript) – Bergi Mar 17 '14 at 20:42

2 Answers2

3

You can use a helper lib like Wait.for-ES6 (I'm the author)

Using wait.for your "list" function will be a standard async function:

 ...
list: function(callback) {
        fs.readdir(this.path, callback);
    },
 ...

but you can call it sequentially IF you're inside a generator:

function* sequentialTask(){
   var directory = new Directory('C:\\');
   var list = yield wait.forMethod(directory,'list');
   console.log(list); // An array of files
}

wait.launchFiber(sequentialTask);

Pros: You can call sequentially any standard async node.js function

Cons: You can only do it inside a generator function*

Another example: You can even do it without the 'list' function since fs.readdir IS a standard async node.js function

var wait=require('wait.for-es6'), fs=require('fs');

function* sequentialTask(){
   var list = yield wait.for(fs.readdir,'C:\\');
   console.log(list); // An array of files
}

wait.launchFiber(sequentialTask);
Lucio M. Tato
  • 5,639
  • 2
  • 31
  • 30
2

You could use promises to do this so that you have proper async handling as well as built-in support for any errors.

list: function() {
  var deferred = q.defer();
  fs.readdir(this.path, deferred.makeNodeResolver());
  return deferred.promise;
}


directory.list()
  .then(function(files) { console.log(files); })
  .fail(function(err) { res.send(500,err); });
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Matt Pileggi
  • 7,126
  • 4
  • 16
  • 18