在之前的$ http完成之后使用$ http

时间:2014-11-24 08:20:29

标签: javascript ajax angularjs

我有3个JSON Web服务,我应该在我的应用程序中使用, 我使用$http从URL加载,我的代码是:

$http.get('http://{url}/users')
    .then(function (result) {
        storeUsers(result);
    });

$http.get('http://{url}/news')
    .then(function (result) {
        storeNews(result);
    });

$http.get('http://{url}/pages')
    .then(function (result) {
        storePages(result);
    });

var users = getUsers();

问题:

1-所有$http一起运行,而不是等到previuse $http完成。

2- var users = getUsers();将在$http完成之前运行。

更新: 我将代码更改为:

 var loadedService = {
            users: false,
            news: false,
            pages: false
        };

function getUsers() {
            deferred = $q.defer();
            $http.get('http://{url}/users')
                .then(function (result) {
                    loadedService.users = result;
                    deferred.resolve('I got users');
                    console.log("Get users");
                });
            return deferred.promise;
        }

function getNews() {
            deferred = $q.defer();
            $http.get('http://{url}/news')
                .then(function (result) {
                    loadedService.news = result;
                    deferred.resolve('I got news');
                    console.log("Get news");
                });
            return deferred.promise;
        }

function getPages() {
            deferred = $q.defer();
            $http.get('http://{url}/pages')
                .then(function (result) {
                    loadedService.pages = result;
                    deferred.resolve('I got pages');
                    console.log("Get pages");
                });
            return deferred.promise;
        }


getNews().then(getUsers()).then(getPages()).then(function () {
     console.log('Done !');
});

当我运行程序时,我会看到:

XHR finished loading: GET "http://{url}/pages". ionic.bundle.js:16185
Get pages sync.js:133
XHR finished loading: GET "http://{url}/users". ionic.bundle.js:16185
Get users sync.js:56
XHR finished loading: GET "http://{url}/news". ionic.bundle.js:16185
Get news sync.js:107

正如您所看到的,首先加载了pages服务,然后是users服务,然后是news,而在我的代码中我说getNews().then(getUsers()).then(getPages())

最后console.log('Done !');没有显示!

6 个答案:

答案 0 :(得分:3)

您可以使用MajoB或Muhammad建议的方式之一,或者您可以使用3个函数返回promise并按照您想要的顺序链接它们。

function getUsers(){
    deferred = $q.defer()

    $http.get('http://{url}/users')
    .success(function (result) {
        storeUsers(result);
        deferred.resolve('I got users')
    }).error(function(data, status, headers, config) {
      // called if an error occurs
      console.log('error');
      deferred.reject(status)
    });

    return deferred.promise
}

function getNews(){
    deferred = $q.defer()

    $http.get('http://{url}/news')
    .success(function (result) {
        storeUsers(result);
        deferred.resolve('I got news')
    }).error(function(data, status, headers, config) {
      // called if an error occurs
      console.log('error');
      deferred.reject(status)
    });

    return deferred.promise
}


function getPages(){
    deferred = $q.defer()

    $http.get('http://{url}/pages')
    .success(function (result) {
        storePages(result);
        deferred.resolve('I got pages')
    }).error(function(data, status, headers, config) {
      // called if an error occurs
      console.log('error');
      deferred.reject(status)
    });;


    return deferred.promise
} 

例如,假设您想在收到新闻后获取页面:

getNews().then(getPages())

每个人都更好地拒绝对错误案例的承诺并对链接进行错误处理:

getNews().then(function() {
  console.log('Success');
  getPages();
}, function() {
  console.log('Failed');
}, function() {
  console.log('Executing... ');
});

当然,链条也会返回你可以处理的承诺。

答案 1 :(得分:2)

你可以链接你的请求:

       $http.get('http://{url}/users')
        .then(function (result) {
            storeUsers(result);
            $http.get('http://{url}/news')
                .then(function (newsResult) {
                    storeNews(newsResult);
                    $http.get('http://{url}/pages')
                        .then(function (pagesResult) {
                        storePages(pagesResult);
                    });
                });
        });

答案 2 :(得分:2)

通过将代码置于成功承诺中,您可以使$http个请求相互运行。

var users; // declare `users` variable
$http.get('http://{url}/users')
    .then(function (result) {
        storeUsers(result);

        // second ajax request
        $http.get('http://{url}/news')
            .then(function (result) {
                storeNews(result);
                // third ajax request goes here
                // .....


                // set the value for users
                users = getUsers();
            });
    });

答案 3 :(得分:1)

这里有一个使用promises和angularJs

的小脚本
$scope.myXhr = function(){

var deferred = $q.defer();

$http({
    url: 'ajax.php',
    method: "POST",
    data:postData,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
    //if request is successful
    .success(function(data,status,headers,config){

        //resolve the promise
        deferred.resolve("request successful");

    })
    //if request is not successful
    .error(function(data,status,headers,config){
        //reject the promise
        deferred.reject("ERROR");
    });

//return the promise
return deferred.promise;
}

$scope.callXhrAsynchronous = function(){

var myPromise = $scope.myXhr();

// wait until the promise return resolve or eject
//"then" has 2 functions (resolveFunction, rejectFunction)
myPromise.then(function(resolve){
    alert(resolve);
    }, function(reject){
    alert(reject)      
});

}

答案 4 :(得分:1)

你可以试试这个:

NoticeService.observeReqUser().then(null,null,function(){
    $http.get('http://{url}/users')
        .then(function (result) {
            storeUsers(result);
            NoticeService.notifyStatusOne()
        });
});

NoticeService.observeReqOne().then(null,null,function(){
    $http.get('http://{url}/news')
        .then(function (result) {
            storeNews(result);
            NoticeService.notifyStatusTwo()
        });
});

NoticeService.observeReqTwo().then(null,null,function(){
    $http.get('http://{url}/pages')
        .then(function (result) {
            storePages(result);
        });
});

var users = getUsers();

您需要创建一个服务来通知请求已完成,以便可以调用下一个

app.service('NoticeService',['$q',function($q){
    var noticegetUserIsDone = $q.defer();

    this.observeReqUser = function() { return noticegetUserIsDone.promise; };
    this.notifyStatusUser = function() { noticegetUserIsDone.notify(); };

    var noticeReqOneIsDone = $q.defer();
    this.observeReqOne = function() { return noticegetUserIsDone.promise; };
    this.notifyStatusOne = function() { noticegetUserIsDone.notify(); };

    var noticeReqTwoIsDone = $q.defer();
    this.observeReqTwo = function() { return noticegetUserIsDone.promise; };
    this.notifyStatusTwo = function() { noticegetUserIsDone.notify(); };
};

您需要从getUser函数的末尾调用NoticeService.notifyStatusUser,以便链开始执行(不要忘记添加您调用它的NoticeService的引用)

答案 5 :(得分:1)

如果我理解你的问题,你可以使用这样的东西:

$http.get('http://{url}/users')
  .then(function (result) {
    storeUsers(result);

    return $http.get('http://{url}/news');
  })
  .then(function (result) {
    storeNews(result);

    return $http.get('http://{url}/pages');
  })
  .then(function (result) {
    storePages(result);

    users = getUsers();
  });

$http.get将返回承诺。

<强>更新

或更清洁的解决方案:

var deferred = $q.defer(),
    users;

$http.get('http://{url}/users')
  .then(function (result) {
    storeUsers(result);

    return $http.get('http://{url}/news');
  })
  .then(function (result) {
    storeNews(result);

    return $http.get('http://{url}/pages');
  })
  .then(function (result) {
    storePages(result);

    deferred.resolve(result);
  });

 deferred.promise.then(function() {
   users = getUsers();
 });

Update2

或更简单:

var request1 = $http.get('http://{url}/users'),
    request2 = $http.get('http://{url}/news'),
    request3 = $http.get('http://{url}/pages');

$q.all([request1, request2, request3]).then(function(result) {
  storeUsers(result[0]);
  storeNews(result[1]);
  storePages(result[2]);

  users = getUsers();
}

但你也需要处理拒绝案件。