2015-07-20 3 views
22

У меня есть следующий сценарий, мне нужны данные с определенного URL-адреса. Я написал функцию, которая принимает параметр 'url'. Внутри функции у меня есть метод $ http.get, который вызывает вызов URL. Данные должны быть возвращены в вызывающую функциюсинхронный http-вызов в angularJS

var getData = function (url) { 
    var data = ""; 

    $http.get(url) 
     .success(function(response, status, headers, config) { 
      data = response; 
     }) 
     .error(function(errResp) { 
      console.log("error fetching url"); 
     }); 
    return data; 
} 

Проблема заключается в следующем, $ http.get асинхронный, перед ответом забирается, функция возвращает. Поэтому вызывающая функция получает данные как пустую строку. Как заставить функцию не возвращаться до тех пор, пока данные не будут получены из URL-адреса?

+0

Что не так с использованием обратного вызова или обещания, как обычно? – Marty

+1

Вы можете вернуть функцию успеха и ошибки, которая может быть использована далее ... – binariedMe

ответ

15

Посмотрите на обещания преодолеть такие проблемы, так как они используются все над местом, в угловатом мире.

Вы должны использовать $q

var getData = function (url) { 
    var data = ""; 
    var deferred = $q.defer(); 

    $http.get(url) 
     .success(function(response, status, headers, config) { 
      deferred.resolve(response); 
     }) 
     .error(function(errResp) { 
      deferred.reject({ message: "Really bad" }); 
     }); 
    return deferred.promise; 
} 

Вот хорошая статья на promises and $q

UPDATE:

FYI, $http сама служба возвращает обещание, поэтому $q не обязательно требуемый в этом сценарии (и, следовательно, anti-pattern).

Но не позволяйте этому быть причиной, чтобы пропустить чтение о $ q и обещаниях.

Таким образом, приведенный выше код эквивалентен следующим образом:

var getData = function (url) { 
    var data = ""; 
    return $http.get(url); 
} 
+0

Как мне получить доступ к значению обещания? – clearScreen

+0

Почему нисходящий? Какая часть ответа неприемлема/неверна? – nalinc

+1

Это общий анти-шаблон: https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns –

5

Типичный способ сделать то, что вы хотите, например, так:

var getData = function(url, callback) { 
    $http.get(url).success(function(response) { 
     callback && callback(response); 
    }); 
}; 

Используется как:

getData('/endpoint', function(data) { 
    console.log(data); 
}); 
4

функция Вам кажется излишним. Просто используйте $http.get(url), так как вы на самом деле ничего не делаете, прежде чем использовать его в любом случае.

var url = 'foo/bar'; 

$http 
    .get(url) 
    .success(function(response, status, headers, config) { 
     $scope.data = response; 
    }) 
    .error(function(errResp) { 
     console.log("error fetching url"); 
    }); 

Или если вам нужно получить доступ к обещанию позже, просто назначьте его переменной;

var promise = $http.get(url); 

// some other code.. 

promise.then(function(data){ 
    //.. do something with data 
}); 
8

Вы можете использовать $ метод q.all() и решить эту проблему

var requestPromise = []; 

var getData = function (url) { 
    var data = ""; 

    var httpPromise = $http.get(url) 
     .success(function(response, status, headers, config) { 
      data = response; 
     }) 
     .error(function(errResp) { 
      console.log("error fetching url"); 
     }); 

    requestPromise.push(httpPromise); 
} 

в вызывающей функции

$q.all(requestPromise).then(function(data) { 

    //this is entered only after http.get is successful 
}); 

убедитесь впрыснуть $ Q как зависимость. Надеюсь, это поможет