0

Similar to this question : Return response from async call Except that the call is within a loop that calls multiple time the asynchronous function.

Specifically, how can the value of s be returned? This code returns undefined. This function is called within a for loop. The library used for ORM is Bookshelfjs. Thanks for the help.

function getUsernameFromDBAsync(userId) {
    var s = "moo";

    new Model.Users({
            idUser: userId
        })
        .fetch()
        .then(function(u) {
            var prenom = u.get('firstName');
            var nom = u.get('familyName');
            s = prenom + " " + nom;
            return s;
        });
}
Community
  • 1
  • 1
io_v
  • 28
  • 1
  • 6

2 Answers2

1

Your aren't really showing how you're doing the loop which makes it a little harder to guess what to recommend. But assuming .fetch().then() returns a promise, here's a general idea with standard ES6 promises built into node.js:

function getUsernameFromDBAsync(userId) {
    var s = "moo";

    return new Model.Users({
        idUser: userId
    }).fetch().then(function (u) {
        var prenom = u.get('firstName');
        var nom = u.get('familyName');
        s = prenom + " " + nom;
        return s;
    });
}

var userIds = [...];
var promises = [];
for (var i = 0; i < userIds.length; i++) {
    promises.push(getUsernameFromDBAsync(userIds[i]));
}

// now set up a .then() handler for when all the promises are done
Promise.all(promises).then(function(names) {
    // process names array here
}, function(err) {
    // process error here
});

If you are using the Bluebird promise library, you could do it a little bit more simply like this:

function getUsernameFromDBAsync(userId) {
    var s = "moo";

    return new Model.Users({
        idUser: userId
    }).fetch().then(function (u) {
        var prenom = u.get('firstName');
        var nom = u.get('familyName');
        s = prenom + " " + nom;
        return s;
    });
}

var userIds = [...];
Promise.map(userIds, getUsernameFromDbAsync).then(function(names) {
    // process names array here
}, function(err) {
    // process error here
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

Var s is unnecessary. Simply return the "prénom nom" string from then's success callback.

function getUsernameFromDBAsync(userId) {
    return new Model.Users({
        idUser: userId
    }).fetch().then(function (u) {
        return u.get('firstName') + ' ' + u.get('familyName');
    });
}

Your "loop" can be achieved with Array.prototype.map() to generate an array of promises, followed by Promise.all(promises).then(...), to receive and handle an array of names when all the promises have resolved.

var promises = userIds.map(function(userId) {
    return getUsernameFromDBAsync(userId);
});
Promise.all(promises).then(function(names) {
    // do something with `names`, which is an array of `prénom nom` strings.
}, function(err) {
    // handler error, eg ...
    console.error(error);
});

Or more succinctly :

Promise.all(userIds.map(getUsernameFromDBAsync)).then(function(names) {
    // do something with `names`, which is an array of `prénom nom` strings.
}, function(err) {
    // handler error, eg ...
    console.error(error);
});
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44