2015-09-07 3 views
2

Я реализую небольшую услугу для своего приложения angularJS, которое делает HTTP-запрос на мой сервер для нескольких текстовых сообщений. Вот моя текущая реализация:Как вернуть объект из службы angularJS ПОСЛЕ HTTP-запроса?

app.factory("postFetcher", ['$http', function($http){ 
    var posts; 

    $http.get('https://cdn.contentful.com/spaces/k2mwszledbge/entries?access_token=afa8ba8572bb0232644d94c80cfd4ae01314cd0589b98551147aab50f7134e30') 
    .then(function(response){ 
     posts = response.data.items; 
    }); 

    return { 
    getList: function(){ 
     return posts; 
    } 
    } 
}]); 

Проблема с этим состоит в том, что запрос HTTP не завершен к тому времени, которое возвратило posts массив. Моя интуиция подсказывает мне поместить функцию возврата в функцию http .then, чтобы она возвращалась только после завершения запроса, однако это недопустимо.

Есть ли способ, которым я могу отложить возврат posts до тех пор, пока HTTP-запрос не будет завершен?

ответ

2

Вы возвращаете обещание вызывающему абоненту. Таким образом, вызывающий может «слушать» обещание. Чтобы вернуть только posts, вы должны добавить then, который возвращает response.data.items. then, который получает цепочку после этого, разрешает это значение.

getList: function(){ 
    return $http.get(...).then(function(response){ 
    // resolve just `response.data.items` to the next attached then which 
    // would be from the caller of getList 
    return response.data.items; 
    }); 
} 

Таким образом, вызывающий абонент также может прикрепить then с обещанием:

postFetcher.getList().then(function(posts){ 
    // use `posts` (which is response.data.items) 
}); 

Для того, чтобы просто назвать его один раз, вы можете хранить обещание в переменной. Затем верните это обещание getList. Прикрепление then к уже разрешенным обещаниям необходимо немедленно решить разрешенное значение.

var posts = $http.get(...).then(function(response){ 
    return response.data.items; 
}); 

return { 
    getList: function(){ 
    return posts; 
    } 
} 

// Call getList() the same way as above 
+0

Nice, это имеет смысл. Однако существует ли способ сохранить HTTP-запрос вне функции возврата? –

+0

Awesome. Последний вопрос, если вы не возражаете. Когда вы храните '$ http.get' в' posts', действительно ли выполняется запрос? Или это не выполняется, пока я не назову 'getList()' в моем контроллере? –

+0

@ByronS выполняется при создании фабрики. – Joseph

3

Используйте promise это один из способов, которые я вижу:
Factory:

app.factory("postFetcher", ['$http', '$q', function($http, $q){ 
    var posts; 

    return { 
     getList: getListFn 
    }; 

    function getListFn(){ 
     var defer=$q.defer(); 

     $http.get('https://cdn.contentful.com/spaces/k2mwszledbge/entries?access_token=afa8ba8572bb0232644d94c80cfd4ae01314cd0589b98551147aab50f7134e30') 
     .then(function(response){ 
      if(response && response.data && response.data.items){ 
       posts = response.data.items; 
       defer.resolve(posts); 
      } 
     }); 

     return defer.promise; 
    };   
}]); 

Использование контроллеров:

postFetcher.getList().then(function(data){ 
//data processing; 
});