2015-11-01 4 views
0

Как и на этот вопрос: Return response from async call За исключением того, что вызов находится в цикле, который вызывает многократную асинхронную функцию.Как вернуть ответ нескольких асинхронных вызовов?

В частности, как можно вернуть значение s? Этот код возвращает undefined. Эта функция вызывается внутри цикла for. Библиотека, используемая для ORM, - Bookshelfjs. Спасибо за помощь.

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; 
     }); 
} 
+0

Вы используете библиотеку обещание? Или узел 4? – jmunsch

+1

ли один или несколько не имеет значения, нужно иметь обратный вызов слишком обрабатывать данные, не могут возвращать данные, поскольку имя предполагает, что оно асинхронно. – vinayakj

+0

Я использую узел 4. Я пробовал обещание. – Xc43

ответ

1

На самом деле вы не показываете, как вы делаете цикл, что делает его немного сложнее догадаться, что рекомендовать. Но если предположить, .fetch().then() возвращается обещание, вот общая идея со стандартными ES6 обещаний, встроенных в 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 
}); 

Если вы используете библиотеку Bluebird обещание, вы могли бы сделать его немного более просто, как это:

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 
}); 
0

Var s не является необходимым. Просто верните строку «préom nom» из обратного вызова успеха.

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

Ваша «петля» может быть достигнута с Array.prototype.map() генерировать массив обещаний, а затем Promise.all(promises).then(...), получать и обрабатывать массив имен, когда все обещания решить.

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); 
}); 

Или более кратко:

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); 
});