简体   繁体   English

仅在Angular中发出$ http请求后,才能运行javascript函数?

[英]How can I run a javascript function only after a $http request has been made in Angular?

I'm working on an Angular.js app which makes some calls to the GitHub API. 我正在使用Angular.js应用程序,该应用程序对GitHub API进行了一些调用。 First, a call is made to retrieve all the repos for a user. 首先,进行调用以检索用户的所有存储库。 Then for each repo, a call is made to retrieve the README. 然后,对于每个存储库,都会调用以检索自述文件。 I have a javascript function which I would like to be run only after all the README API calls are completed. 我有一个javascript函数,只有在所有README API调用完成后才能运行。

Here is my controller: 这是我的控制器:

readmeSearch.controller('ReadMeSearchController', ['RepoSearch', 'ReadMeSearch', function(RepoSearch, ReadMeSearch) {

  var self = this;
  self.gitRepoNames = [];
  self.readMes = [];
  self.noReadMes = [];

  self.doSearch = function() {
    RepoSearch.query(self.username)
      .then(function(repoResponse) {
        addRepoNames(repoResponse);
        for(var i = 0; i< self.gitRepoNames.length; i++) {
          (function(i) {
            ReadMeSearch.query(self.username, self.gitRepoNames[i])
              .then(function(readMeResponse) {
                addToReposWithReadMes(readMeResponse, i);
              }).catch(function(e){
                addToReposWithoutReadMes(repoResponse, i);
              });
          })(i);
        };
      });
  };

  addRepoNames = function(response) {
    self.searchResult = response.data;
    for(var i = 0; i < self.searchResult.length; i++) {
      var name = self.searchResult[i]['name']
      self.gitRepoNames.push(name);
    };
  };

  addToReposWithReadMes = function(response, i) {
    self.readMes.push(
      {
        name: self.gitRepoNames[i],
        size: parseInt(response.data["size"]),
        url: response.data["html_url"]
      }
    );
  };

  addToReposWithoutReadMes = function(response, i) {
    self.noReadMes.push(
      {
        name: self.gitRepoNames[i]
      }
    );
  };

  percentageOfReposWithReadMes = function() {
    var percentage;
    percentage = (self.noReadMes.length / self.gitRepoNames.length) * 100
    self.readMePercentage = percentage.toFixed(1);
  };

}]);

The README API calls using the ReadMeSearch factory populate two arrays, one for repos with READMEs and one for repos without READMEs. 使用ReadMeSearch工厂的README API调用将填充两个数组,一个数组用于包含README的存储库,另一个数组用于不具有README的存储库。 I would like to run the function percentageOfReposWithReadMes only after the ReadMeSearch.query has been completed for all the repos in self.gitRepoNames . 我想运行的功能percentageOfReposWithReadMes唯一的后ReadMeSearch.query已经完成了所有回购self.gitRepoNames

I've tried using .then after the RepoSearch.query but this doesn't seem to work. 我已经尝试使用.then在后RepoSearch.query但这似乎并没有工作。 I think I'm a bit muddled in my understanding of Angular promises and the .then function. 我对Angular Promise和.then函数的理解有些.then Any help would be greatly appreciated. 任何帮助将不胜感激。

You could try using $q.all , this will reslove an array of promises, and .then after all these are done, you would run your function. 你可以尝试使用$q.all ,这将reslove承诺的数组, .then所有这些完成之后,你可以运行你的函数。

I'm having trouble trying this myself, would be easier if you had a plunkr or something. 我自己尝试尝试时遇到麻烦,如果您有笨拙的东西会更容易。

I did find this thread that explains this pretty good, maybe you can find your answer there. 我确实找到了解释这一点的线程,也许您可​​以在那里找到答案。

I think you have to create two defers and resolve then when the loop finish. 我认为您必须创建两个延迟,然后在循环结束时解决。 With $q.all you can wait for till both refers finish and call the percentageOfReposWithReadMes function. 随着$ q.all你可以等待,直到两个指完成并调用percentageOfReposWithReadMes功能。

  readmeSearch.controller('ReadMeSearchController', ['RepoSearch', 'ReadMeSearch', '$q', function(RepoSearch, ReadMeSearch, $q) {

  var self = this;
  var gitRepoNameDefer;
  var noReadMesDefer;
  self.gitRepoNames = [];
  self.readMes = [];
  self.noReadMes = [];


  self.doSearch = function() {
    RepoSearch.query(self.username)
      .then(function(repoResponse) {
        gitRepoNameDefer = $q.defer();
        noReadMesDefer = $q.defer();
        addRepoNames(repoResponse);
        for(var i = 0; i< self.gitRepoNames.length; i++) {
          (function(i) {
            ReadMeSearch.query(self.username, self.gitRepoNames[i])
              .then(function(readMeResponse) {
                addToReposWithReadMes(readMeResponse, i);
              }).catch(function(e){
                addToReposWithoutReadMes(repoResponse, i);
              }).finally(function () {
                 finishDefers(i, self.gitRepoNames.length - 1);
              });
          })(i);
        }
        $q.all([gitRepoNameDefer, noReadMesDefer ]).then(fucntion () {
          percentageOfReposWithReadMes();
        });
      });
  };

  addRepoNames = function(response) {
    self.searchResult = response.data;
    for(var i = 0; i < self.searchResult.length; i++) {
      var name = self.searchResult[i]['name']
      self.gitRepoNames.push(name);

    };
  };

  addToReposWithReadMes = function(response, i) {
    self.readMes.push(
      {
        name: self.gitRepoNames[i],
        size: parseInt(response.data["size"]),
        url: response.data["html_url"]
      }
    );

  };

  addToReposWithoutReadMes = function(response, i) {
    self.noReadMes.push(
      {
        name: self.gitRepoNames[i]
      }
    );

  };

 function finishDefers (index, limit) {
   if (index === limit) {
      gitRepoNameDefer.resolve(self.readMes);
      noReadMesDefer.resolve(self.noReadMes);
   }
 }

 function percentageOfReposWithReadMes () {
    var percentage;
    percentage = (self.noReadMes.length / self.gitRepoNames.length) * 100
    self.readMePercentage = percentage.toFixed(1);
  };

}]);

Return your promises and chain from those promises 回到你的承诺,并从这些承诺

 self.doSearch = function() {
    var namesPromise = 
        RepoSearch.query(self.username)
            .then(function(repoResponse) {
                 addRepoNames(repoResponse);
                 //return promises for chaining
                 return lookupNamesPromises(repoResponse);
            }) .catch (function (error) {
                 //log error
            });
    //chain from promise
    namesPromise.then (function(promises) {
        $q.all(promises).finally( function() {
            percentageOfReposWithReadMes();
        })
    });
    //return promise for chaining elsewhere
    return namesPromise;
  };

Lookup function returns an array of promise. 查找函数返回一个promise数组。

  self.lookupNamesPromises = function (repoResponse) {
    var namesPromises = [];
    for(var i = 0; i< self.gitRepoNames.length; i++) {
          //begin IIFE closure
          (function(i) {
              var p = (ReadMeSearch.query(self.username, self.gitRepoNames[i])
                       .then(function(readMeResponse) {
                           addToReposWithReadMes(readMeResponse, i);
                           return readMeResponse;
                       }).catch(function(e){
                           addToReposWithoutReadMes(e, i);
                           return e;
                       })
              );
              namesPromises.push(p);
          })(i);
          //end IIFE closure
    }
           //return promises for chaining
    return namesPromises;
  };

By chaining your promises, subsequent functions will wait for previous functions to complete. 通过链接您的诺言,后续功能将等待之前的功能完成。 The rule of thumb in functional programming is always return something . 函数式编程的经验法则总是返回一些东西

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我希望只有在验证HTML5表单输入后才能运行javascript函数 - I want to have a javascript function run only after HTML5 form input has been validated Angular 生命周期:我如何执行 javascript function 之后 ZC31C335EF37283C451B18BA0DD1 已初始化? - Angular lifecycle: How do I execute a javascript function AFTER Angular has been initialized? 如何在“等待”请求完成后立即执行函数? - How can I execute a function right after an "await" request has been completed? Google Loader运行后,我可以运行JavaScript函数吗? - Can I run a JavaScript function AFTER Google Loader has run? https请求循环,在发出最后一个请求后调用函数节点 - https requests in loop, call function after last request has been made node PHP:如果仅在没有JavaScript的情况下尝试填写表单中的字段,则显示消息 - PHP: display message if a field in a form isn't filled only after attempt has been made without javascript 使用Jquery / Javascript找到元素后如何运行函数 - How to run a function once after element has been found with Jquery/Javascript Javascript和回调和deferred。 如何在google gmail API请求完成后运行某个功能? - Javascript and callbacks and defered. How can I run a function after a google gmail API request completes? 我想在输入字段输入后运行函数 - I want to run a function after an input field has been entered 可变大小循环内的http请求,只有在最后一个请求完成后才能做某事(JavaScript) - http requests inside loop of variable size, how to do something only after last request has finished (JavaScript)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM