[英]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.