0

I'm trying to use the Q promise library to chain together a couple of async methods to change an array of objects I've got. I think I'm close, but I'm making a mistake somewhere and getting the error:

       resolve(sizes);
       ^
    TypeError: object is not a function

The array is like this:

var sizes = [{
    "oldName": "10",
    "newName": "10_1",
    "sizeExistsInDest": false,
    "sizeExistsInSrc": false,
    "filesInSrc": [],
    "dirsInDest": [],
    "filesInDest": [],
    "filesToCopy": []
}.....]; //ten or so elements

Then I have two functions I'm trying to call in sequence. Like when one is complete, then, call the next.

var getSrcDirs= function(resolve) {
    async.eachLimit(sizes, 1, function(size, callback){
       var srcDir = path.join(src, size.oldName);
        if (exists(srcDir)){ //exists is from the is-there module
            size.sizeExistsInSrc = true;
        }
        callback();
    }, function(){
        resolve(sizes);
    });
};

var getSrcFiles = function(resolve){
    async.each(sizes, function(size, callback){
        if(size.sizeExistsInSrc){ //only process if the "exists" flag has been set to true
            var fullSrc = path.join(src, size.oldName); //format like 'rootSrc/10'
            fs.readdir(fullSrc, function(err, srcFiles){
                size.filesInSrc = srcFiles;
                callback(); //re-enter each loop once files have been set to `filesInSrc` array
            });
        }else{
            callback(); //if directory doesn't exist, re-enter each loop
        }

    }, function(){
        resolve(sizes);
    });
};

var getFileData = function () {
    var deferred = Q.defer();
    getSrcDirs(deferred.resolve);
    return deferred.promise;
};

When I call

var srcFiles = getFileData()

a console print of srcFiles shows the modified sizes array correctly. However when adding a then.

var srcFiles = getFileData().then(getSrcFiles);

I think I should see files added to the sizes array, I get the error I specified above. I'd like to chain a couple more thens, but I cannot seem to modify my array more than once.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1252748
  • 14,597
  • 32
  • 109
  • 229
  • Your `getSrcFiles` callback to `.then(…)` will be called with the `sizes` array as its argument, not some `resolve` function! – Bergi Jul 30 '15 at 21:17
  • The basic mistake I see here is to use promises together with async.js. You should try using only promises. – Bergi Jul 30 '15 at 21:18
  • Um, that `getSrcDirs` function appears to be synchronous, why are you using callbacks/`async.eachLimit` here? – Bergi Jul 30 '15 at 21:19
  • @Bergi Several problem. My issue is that the number of files I'm attempting to move is more than node's open file limit. I have tried to use `eachLimit` in order to get around this, but it seemed not to limit the number of files the way I thought it would, as the same errors have persisted. I thought by containing each `each` loop within a segment of a `then` chain, I could compartmentalize their execution, so that I would be sure my reads and writes executed in succession and did not meet with any race condition mishap. Using promises, should the loops be synchronous `forEach`? Or..? – 1252748 Jul 30 '15 at 21:46
  • @Bergi re: your first comment, does this mean I should be using something like `return sizes` rather than `resolve promises`? Thanks for your input. – 1252748 Jul 30 '15 at 21:47
  • What is that `exists` function? Is it actually the asynchronous `fs.exists`? – Bergi Jul 30 '15 at 21:49
  • No, to fix `getSrcFiles` you should make it take `sizes` as a parameter, and return a promise for the result (not using callbacks) – Bergi Jul 30 '15 at 21:51
  • @Bergi No that's been deprecated, I'm using https://www.npmjs.com/package/is-there – 1252748 Jul 30 '15 at 21:52
  • @Bergi So that's a "no" to the synchronous `forEach`? How would the return of my promise look? When you say "without a callback", where would I return the promise? – 1252748 Jul 30 '15 at 21:56
  • Ah, a wrapper that re-introduced the deprecated function… Still, you are using the synchronous version of `exists`, which you shouldn't. – Bergi Jul 30 '15 at 21:58
  • A loop with promises is either `reduce` (for sequential execution) or `Promise.all`+`map` (for parallel execution). I'm still searching for the link to point you at – Bergi Jul 30 '15 at 21:59
  • @Bergi thanks, I look forward to reading it. Would you mind taking a look at my update later? Thanks! – 1252748 Jul 30 '15 at 22:15
  • @bergi, were you able to find the example you were thinking of, or perhaps can you give me an example of how the pattern you describe would work? Thanks. – 1252748 Jul 31 '15 at 14:52
  • Have a look at [this answer](http://stackoverflow.com/a/24586168/1048572) for some patterns. I think we don't have a canonical yet. – Bergi Jul 31 '15 at 14:56

0 Answers0