我正在使用一个Angular.js应用程序来调用GitHub API。首先,调用以检索用户的所有存储库。然后,对于每个repo,进行调用以检索README。我有一个javascript函数,我希望只有在所有README API调用完成后才能运行。
这是我的控制器:
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);
};
}]);
使用ReadMeSearch工厂的README API调用填充两个数组,一个用于带有README的repos,另一个用于没有README的repos。我想在percentageOfReposWithReadMes
完成ReadMeSearch.query
中的所有回购后,才能运行self.gitRepoNames
函数。
我已尝试在.then
之后使用RepoSearch.query
,但这似乎不起作用。我认为我对Angular承诺和.then
函数的理解有点混乱。任何帮助将不胜感激。
答案 0 :(得分:0)
您可以尝试使用$q.all
,这将重新获得一系列承诺,.then
完成所有这些后,您将运行您的功能。
我自己尝试这个问题,如果你有一个笨蛋或其他东西会更容易。
我确实找到了解释这个问题的this帖子,也许你可以在那里找到答案。
答案 1 :(得分:0)
我认为你必须创建两个延迟并在循环结束时解决。使用$ q.all,您可以等待两个引用完成并调用<?php
$dates = "";
foreach ($check_ins as $check_in):
$dates .= '<option value= "' . $check_in['check_in'] . '">' . $check_in['check_in'] . '</option>';
endforeach;
$nights = $check_ins[0]['nights'];
if (!empty($_POST['newDate'])){
$nights = 0;
foreach ($check_ins as $check_in):
if ($check_in['check_in'] === $_POST['newDate']){
$nights += $check_in['nights'];
}
endforeach;
}
?>
<html>
<head>
<title>Bookings stats</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
/*function dynamicDates() {
var d = $("#dates").val();
$.post("metrily.php", { newDate: d });
}*/
function dynamicDates(newDate){
if (newDate == ""){
document.getElementById("stats").innerHTML = "";
return;
} else {
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("stats").innerHTML = xmlhttp.responseTest;
}
};
xmlhttp.open("POST", "hotel.php", true);
xmlhttp.send("newDate=" + newDate);
}
}
</script>
</head>
<body>
<b>Check-in: </b>
<select id="dates" name="check_in" onchange="dynamicDates(this.value)"><?php echo $dates; ?></select>
<br></br>
<div id="stats">
<b>Nights: </b><?php echo $nights; ?>
</div>
</body>
</html>
函数。
percentageOfReposWithReadMes
答案 2 :(得分:0)
从这些承诺中退回您的承诺和链
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函数返回一个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;
};
通过链接您的承诺,后续功能将等待以前的功能完成。函数式编程的经验法则总是返回。