Javascript for循环中的异步方法
我创建了一个简单的chrome扩展,它可以遍历用户的浏览历史,并统计与一系列特定编程语言匹配的结果数量。问题是我想迭代数组的长度,并为数组列表中的每个字符串调用一个异步chrome方法。可在此处找到扩展名: 问题代码是:Javascript for循环中的异步方法,javascript,arrays,asynchronous,for-loop,Javascript,Arrays,Asynchronous,For Loop,我创建了一个简单的chrome扩展,它可以遍历用户的浏览历史,并统计与一系列特定编程语言匹配的结果数量。问题是我想迭代数组的长度,并为数组列表中的每个字符串调用一个异步chrome方法。可在此处找到扩展名: 问题代码是: function myfunction() { var listOfLanguages = ["Java", "C", "C++", "PHP", "C#", "Visual Basic", "Python", "Objective-C", "Perl", "Java
function myfunction() {
var listOfLanguages = ["Java", "C", "C++", "PHP", "C#", "Visual Basic", "Python", "Objective-C", "Perl", "Javascript", "Ruby"];
var mostPopular = "not a programmer";
var totalResults = 0;
for (var i = 0, len = listOfLanguages.length; i < len; i++) {
(function (i) {
setTimeout(function () {
chrome.history.search({
text: listOfLanguages[i],
maxResults: 500
}, function (callback) {
var countOfResults = callback.length;
var langOfResults = listOfLanguages[i];
if (countOfResults > totalResults) {
totalResults = countOfResults;
mostPopular = langOfResults;
}
if (i == 10) {
var lang = mostPopular;
console.log(mostPopular);
switch (lang) {
case "Java":
document.write('<img src="assets/images/java.png"/>');
break;
case "C#":
document.write('<img src="assets/images/C#.jpg"/>');
break;
case "C":
document.write('<img src="assets/images/C.png"/>');
break;
case "C++":
document.write('<img src="assets/images/c++.png"/>');
break;
case "Objective-C":
document.write('<img src="assets/images/objectivec.png"/>');
break;
case "Perl":
document.write('<img src="assets/images/perl.gif"/>');
break;
case "PHP":
document.write('<img src="assets/images/php.png"/>');
break;
case "Python":
document.write('<img src="assets/images/python.jpg"/>');
break;
case "Ruby":
document.write('<img src="assets/images/ruby.png"/>');
break;
case "Visual Basic":
document.write('<img src="assets/images/vb.png"/>');
default:
document.write('<img src="assets/images/noprog.png"/>');
}
}
});
}, i * 1000);
})(i);
}
}
window.onload = myfunction;
函数myfunction(){
var listOfLanguages=[“Java”、“C”、“C++”、“PHP”、“C#”、“Visual Basic”、“Python”、“Objective-C”、“Perl”、“Javascript”、“Ruby”];
var mostPopular=“不是程序员”;
var totalResults=0;
for(var i=0,len=listOfLanguages.length;itotalResults){
totalResults=结果的计数;
mostPopular=langOfResults;
}
如果(i==10){
var lang=大多数人;
console.log(大多数流行);
交换机(lang){
案例“Java”:
文件。写(“”);
打破
案例“C#”:
文件。写(“”);
打破
案例“C”:
文件。写(“”);
打破
案例“C++”:
文件。写(“”);
打破
案例“目标-C”:
文件。写(“”);
打破
案例“Perl”:
文件。写(“”);
打破
案例“PHP”:
文件。写(“”);
打破
案例“Python”:
文件。写(“”);
打破
案例“Ruby”:
文件。写(“”);
打破
案例“Visual Basic”:
文件。写(“”);
违约:
文件。写(“”);
}
}
});
},i*1000);
})(i) );
}
}
window.onload=myfunction;
我通过在每次迭代中设置一个超时函数来找到解决方法,但这不是一个优雅的解决方案。我在网上读了很多文章来处理这个问题,其中涉及到添加更多我不理解的迭代级别。希望有人能解释处理这个问题的正确方法,很多人都遇到了这个问题。如果我理解正确的话,类似的方法可能会奏效 将传递给
setTimeout
的匿名函数作为命名函数。现在,通过让它接受一系列语言作为参数,使它成为一个递归函数。在函数末尾,删除第一种语言,然后使用剩余的数组递归。当数组为空时,停止递归。然后用原始语言列表作为参数调用这个函数。这样,下一次搜索迭代只会在当前迭代完成时发生
这是一段伪代码
var search = function(languages) {
var currentLanguage = languages[0];
//...
if (languages.length > 1) {
search(languages.slice(1));
}
};
search(listOfLanguages);
<>编辑:也考虑使用一个MAP而不是一个Switter语句。将语言映射到正确的图像,如下所示:
var imageMap = {
"Objective-C": "objectivec.png",
"Visual Basic": "vb.png"
// etc...
};
做到这一点的最好方法是计算出的异步调用的数量,并在它们返回时递减
var outstandingCalls = 0;
var resultSet = [];
for (var i = 0; i < 100; i++) {
outstandingCalls++;
someAsyncCall(function(result) {
outstandingCalls--;
resultSet.push(result);
if (outstandingCalls == 0) done();
});
}
function done() {
//done...
}
var-outstandingCalls=0;
var结果集=[];
对于(变量i=0;i<100;i++){
杰出的呼叫++;
someAsyncCall(函数(结果){
未完成的呼叫--;
结果集推送(结果);
如果(未完成调用==0)完成();
});
}
函数完成(){
//完成。。。
}
(代码未经验证,但希望您能理解)
在调用done()之前,还需要确保for循环已完成