Я хочу отправить пользователю список новых книг. Пока что код ниже работает нормально. Проблема в том, что я не хочу отправлять книгу несколько раз, поэтому я хочу их отфильтровать.Множественная функция Q.all внутри?
Текущий код работает отлично:
function checkActiveBooks(books) {
var queue = _(books).map(function(book) {
var deferred = Q.defer();
// Get all alerts on given keywords
request('http://localhost:5000/books?l=0&q=' + book.name, function(error, response, body) {
if (error) {
deferred.reject(error);
}
var books = JSON.parse(body);
if (!_.isEmpty(books)) {
// Loop through users of current book.
var userBooks = _(book.users).map(function(user) {
// Save object for this user with name and deals.
return {
user: user,
book: book.name,
books: books
}
});
if (_.isEmpty(userBooks)) {
deferred.resolve(null);
} else {
deferred.resolve(userBooks);
}
} else {
deferred.resolve(null);
}
});
return deferred.promise;
});
return Q.all(queue);
}
Но теперь я хочу, чтобы уже фильтровать послал книги:
function checkActiveBooks(books) {
var queue = _(books).map(function(book) {
var deferred = Q.defer();
// Get all alerts on given keywords
request('http://localhost:5000/books?l=0&q=' + book.name, function(error, response, body) {
if (error) {
deferred.reject(error);
}
var books = JSON.parse(body);
if (!_.isEmpty(books)) {
// Loop through users of current book.
var userBooks = _(book.users).map(function(user) {
var defer = Q.defer();
var userBook = user.userBook.dataValues;
// Check per given UserBook which books are already sent to the user by mail
checkSentBooks(userBook).then(function(sentBooks) {
// Filter books which are already sent.
var leftBooks = _.reject(books, function(obj) {
return sentBooks.indexOf(obj.id) > -1;
});
// Save object for this user with name and deals.
var result = {
user: user,
book: book.name,
books: leftBooks
}
return deferred.resolve(result);
});
return Q.all(userBooks);
} else {
deferred.resolve(null);
}
});
return deferred.promise;
});
return Q.all(queue);
}
Но приведенный выше код не работает. Он не прекращает цикл. Я думал, что имеет смысл использовать q.all дважды, потому что он содержит две петли. Но я думаю, что я делаю это неправильно ...
Что вы имеете в виду «это не останавливает цикл»? – Bergi
Единственная проблема, которую я вижу, заключается в том, что 'checkSentBooks' можно вызвать до того, как будут выполнены все' checkActiveBooks' 'request(). Есть ли состояние гонки на вашем сервере, что они зависят друг от друга? – Bergi
Ну, это прекратило цикл, но я не ответил, плохой. Но проблема, что checkSentBook асинхронна, является проблемой. Он также содержит обещание, потому что checkSentBook выполняет вызов в базу данных с помощью Sequelize JS. Вот почему у меня было два q.all. Моя проблема в том, что функция .map не дождалась возврата функции checkSentBook результата базы данных, поэтому мой объект книг внутри массива остается пустым. Двойной q.all не работает. Проверьте ответ Бенджамина ниже и мои ответы на этот ответ. –