Правильный способ вызвать функцию обратного вызова после того, как все данные были получены из mongoDB в Express?

0

Я пишу веб-приложение с функцией сообщения.

Разговор в моем приложении определяется как между двумя отдельными пользователями. Например, если Адам только что создал профиль и отправил 1 сообщение Джейн и 3 сообщения Джеку. У него было бы 2 Беседы, но всего 4 сообщения.

В следующем коде на стороне Express я пытаюсь получить все разговоры для данного пользователя в базе данных. Как только это будет завершено, отправьте эти данные на сторону углового контроллера. Каков правильный способ сделать это в api.js ниже, учитывая, что JS является асинхронным?

общественные /JavaScripts/main_controller.js

var mainApp = angular.module('myApp', ['ngRoute', 'btford.socket-io', 'xeditable']);
...
mainApp.controller('MessagesController', function($scope, $http, userSessionService, socket, focus){
  console.log("MessagesController running");
  $scope.messageDisplay = '';
  $scope.username = userSessionService.getUserSession().username;

  $http({
      url: '/loadConversations', 
      // url: '/about', 
      method: "GET"
    })
    .success(function(response) {
      console.log("success with loadConversations: ", response);
      console.log(response[0].data);
    });
....
})

маршруты/api.js:

....

router.route('/loadConversations')
.get(isAuthenticated, function(req, res) {
var result = [];
  //Find Conversation with each and all distinct users
  for(var i = 0; i < req.user.conversations.length; i++){
Conversation.findOne({'_id': req.user.conversations[i]}, function(err, conversation){
  if(err){
    console.log(err);
  }
  if(conversation){
    var contactUsername = (conversation.initiatorUsername == req.user.username) ? conversation.responderUsername : conversation.initiatorUsername;
    var lastMessage = conversation.messages[conversation.messages.length-1].content;
    var dateOfMessage = conversation.messages[conversation.messages.length-1].date;
    var resultJSON = {contactUsername: contactUsername,
                            lastMessage: lastMessage,
                            dateOfMessage: dateOfMessage};
    result.push(resultJSON);

  } else {
    console.log("conversation not found!");
  }
  //Below is not working, where should I put res.json(result)?
  // if(result.length == req.user.conversations.length){
  //   res.json(result);
  // }
});

}});

1 ответ

0

Я не уверен, что вы даже попросили об этом, но я думаю, вы должны немного переписать свой код контроллера.

В этом примере обещание возвращается после $http(...). Вместо использования.success я бы рекомендовал использовать. Then. Важно понять разницу между ними, поэтому я попытаюсь кратко объяснить. Здесь метод .success() в угловом исходном коде:

promise.success = function(fn) {
// ...
promise.then(function(response) {
    fn(response.data, response.status, response.headers, config);
});
    return promise;
};

и вот их официальная документация

.success же, как и. .then кроме success, возьмет первый аргумент успешного результата вызова, поэтому вам не придется записывать response.data. Это удобно, но если вы когда-либо используете кеширование или хотите сцепить другие обещания, это станет болью в заднице. Вот моя альтернатива для вас.

$http({
  url: '/loadConversations', 
  // url: '/about', 
  method: "GET"
})
.then(function(response) {
  // this is your success callback
  console.log("success with loadConversations: ", response);
  console.log(response[0].data);
}, function(error) {
  // if the service call doesnt return 200, we fire this
  console.log(error); 
});

Этот консольный журнал будет выполняться асинхронно в этой реализации и будет легче поддерживать, чем использовать .success.

EDIT: для маршрутов /api.js, я думаю, вам просто нужно вернуть массив results

if(result.length == req.user.conversations.length){
  return result;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню