2017-01-27 5 views
1

В моем проекте я использую async для асинхронных запросов к базе данных и у меня есть этот кусок кода:асинхронной не возвращает данные в обратный вызов после того, как мангуст обновить

async.auto({ 
     one: function(callback){ 
      getFriendsIds(userId, callback) 
     }, 
     two: ['one', function(callback, results){ 
      getFriendsDetails(results.one, callback); 
     }], 
     final: ['one', 'two', function(callback, results) { 
      res.status(200).send(results.two); 
      return; 
     }], 
    }, function(err) { 
     if (err) { 
      sendError(res, err); 
      return; 
     } 
    }); 

Метод возвращения идентификаторов друзей выглядит следующим образом :

function getFriendsIds(userId, callback) { 
    var query = User.findOne({_id: userId}); 

    query.exec(function(err, user) { 
     if(err) { 
      callback(err); 
      return; 
     } 

     return callback(null, user.friendsIds); 
    }); 
} 

Он отлично работал. Функция вернула идентификаторы друзей, и я использовал их в «двух» блоке асинхронного вызова.

После модернизации mongoose от 4.3.7 до 4.7.8 он прекратил работать. Я начал получать предупреждение Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead, и идентификаторы не возвращались в обратном вызове.

Так что я добавил bluebird пакет к проекту и подключил его к mongoose. Теперь предупреждение исчезло, но идентификаторы все еще не возвращены в обратном вызове.

Я также обновил async до последней версии, но это тоже не помогло.

Есть ли что-нибудь еще, что я должен сделать, чтобы сделать эту работу?

+0

сделал вас попробовал такие обещания, mongoose.promise = require ('bluebired), mongoose.Promise = global.Promise, mongoose .Promise = require ('q'). Обещание? –

ответ

1

Идея использования обещаний - не использовать обратные вызовы, и вы по-прежнему используете обратные вызовы в своем коде.

Предполагая, что вам требуется Bluebird как

mongoose.Promise = require('bluebird');

вашей функции должны теперь вместо того, чтобы выглядеть следующим образом:

function getFriendsIds(userId) { 
    //This will now be a bluebird promise 
    //that you can return 
    return User.findOne({_id: userId}).exec() 
     .then(function(user){ 
      //return the friendIds (this is wrapped in a promise and resolved) 
      return user.friendsIds; 
     }); 
} 

Вернувшийся значение функции будет массив из user.friendsIds. Воспользовавшись возможностью объединения обещаний, вы можете написать функцию, которая извлекает детали каждого друга, и возвращает это как массив из friendDetails.

function getFriendsDetails(friendIds) { 
    //For each friendId in friendIds, get the details from another function 
    //(Promise = require("bluebird") as well) 
    return Promise.map(friendIds, function(friendId) { 
     //You'll have to define the getDetailsOfFriend function 
     return getDetailsOfFriend(friendId); 
    }); 
} 

и просто назвать это как

getFriendsIds(123) 
    .then(getFriendsDetails) //the resolved value from previous function will be passed as argument 
    .then(function(friendDetails) { 
     //friendDetails is an array of the details of each friend of the user with id 123 
    }) 
    .catch(function(error){ 
     //Handle errors 
    }); 

Если вы хотите писать меньше кода, вы можете позволить Bluebird promisify функции мангуста как этот

Promise.promisify(User.findOne)(123) 
    .then(function(user){ 
     return user.friendsIds; 
    }) 
    .then(getFriendsDetails) 
    .then(function(friendDetails) { 
     //Return or do something with the details 
    }) 
    .catch(function(error){ 
     //Handle error 
    }); 
+0

Спасибо, это почти работает для меня :) Последнее, что мне нужно сделать, это передать второй аргумент функции getFriendsDetails вместо '' getFriendsDetails (ids) '' он должен быть '' getFriendsDetails (ids, myId) ''. Как мне это сделать? Я пробовал использовать '.bind (null, myId)' ', но это не сработало. – CorrieSparrow

+0

Если вы хотите передать больше, чем ранее разрешенное значение, следующей функции '.then()', просто напишите его как. .then (function (userIds) {return getFriendsDetails (userIds, myId);}) ', предполагая, что 'myId' определяется ранее. Я не буду обновлять ответ, поскольку он немного отличается от исходного вопроса. –

+0

Спасибо, все работает сейчас! – CorrieSparrow

 Смежные вопросы

  • Нет связанных вопросов^_^