Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate an array synchronously using lodash, underscore or bluebird [closed]

I have an array that contains filenames at each index. I want to download those files one at a time (synchronously). I know about 'Async' module. But I want to know whether any functions in Lodash or Underscore or Bluebird library supports this functionality.

like image 408
Nidhin David Avatar asked Dec 23 '15 12:12

Nidhin David


2 Answers

You can use bluebird's Promise.mapSeries:

var files = [
    'file1',
    'file2'
];

var result = Promise.mapSeries(files, function(file) {
    return downloadFile(file); // << the return must be a promise
});

Depending on what you use to download file, you may have to build a promise or not.

Update 1

An exemple of a downloadFile() function using only nodejs:

var http = require('http');
var path = require('path');
var fs = require('fs');

function downloadFile(file) {
    console.time('downloaded in');
    var name = path.basename(file);

    return new Promise(function (resolve, reject) {
        http.get(file, function (res) {
            res.on('data', function (chunk) {
                fs.appendFileSync(name, chunk);
            });

            res.on('end', function () {
                console.timeEnd('downloaded in');
                resolve(name);
            });
        });
    });
}

Update 2

As Gorgi Kosev suggested, building a chain of promises using a loop works too:

var p = Promise.resolve();
files.forEach(function(file) {
    p = p.then(downloadFile.bind(null, file));
});

p.then(_ => console.log('done'));

A chain of promise will get you only the result of the last promise in the chain while mapSeries() gives you an array with the result of each promise.

like image 75
Shanoor Avatar answered Oct 24 '22 21:10

Shanoor


using Bluebird, there is a situation similar to yours with an answer here: How to chain a variable number of promises in Q, in order?

This seems like a decent solution but in my opinion much less readable and elegant as async.eachSeries(I know you said you don`t want the 'async' solution but maybe you can reconsider.

like image 25
gibson Avatar answered Oct 24 '22 20:10

gibson