Ajax API 嵌套循环调用需要按顺序执行
Ajax API calls in nested loop need to be executed in order
假设您有一个场景需要在页面的文本区域中创建 .csv 输出...
所以我有 2 个数组,我循环嵌套在另一个数组中。嵌套循环的结果是通过 ajax 调用的查询...我需要将 ajax 调用的结果附加到文本区域中。
我的问题是如何按照请求的顺序打印出结果(基本上是查询数组中的顺序)
//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery= ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');
//outter loop
$.each(outerQuery, function(outerIndex, outer){
//Print the row
$csvText.append('Row' + outer +'\r\n\r\n');
//Nested inner loop (that should execute in order regarless or the time of the api call)
innerQuery.reduce(function(innerCallback, inner, innerIndex){
return innerCallback.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});//end inner callback
},Promise.resolve());
});
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 1000) + 1));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
正如您在代码段中看到的结果 运行 非常奇怪
理想情况下,它们应该像这样打印:
RowA
1,2,3,4,5,6
RowB
1,2,3,4,5,6
RowC
1,2,3,4,5,6
.
.
.
我从 那里得到的 innerQuery.reduce 这真的很有帮助,感谢 @jfriend00
谢谢大家
您可以使用 .queue()
, .promise()
到 return 函数,顺序对应于数组中的索引
//example array to loop.
var outerQuery = ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery = ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
var $csvText = $('#some-text-area');
// create `"outerQuery"` queue
$csvText.queue("outerQuery", $.map(outerQuery, function(outer, index) {
return function(next) {
$(this).append((index > 0 ? '\r\n\r\n' : "")
+ 'Row' + outer + '\r\n\r\n')
// create `"innerQuery"` queue
.queue("innerQueue", $.map(innerQuery, function(inner, innerIndex) {
return function(_next) {
return GoogleAnalyticsAPI(inner).then(function(response) {
$csvText.append(response.column1 + ',');
// call `_next` function in `"innerQueue"`
}).then(_next);
}
})).dequeue("innerQueue").promise("innerQueue")
// call `next` function in `"outerQueue"`
// when all functions in current `innerIndex`
// of `innerQueue` array , `"innerQueue"` completes
.then(next)
}
})).dequeue("outerQuery");
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({
column1: val
});
}, Math.floor((Math.random() * 1000) + 1));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
您可以继续使用在 的内部 .reduce()
循环中使用的相同逻辑,并将其应用于外部循环。此外,您可以使用普通 Javascript 概念进行同步。
这样做的关键是来自先前答案的内部 .reduce()
循环 returns 只有当内部循环中的所有链式异步操作完成时才会解决的承诺。您可以像这样使用该承诺来控制和同步外循环:
//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var innerQuery= ['1', '2', '3', '4', '5', '6'];
//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');
//outer loop
outerQuery.reduce(function(outerP, outerItem) {
return outerP.then(function() {
//Print the row
$csvText.append('Row' + outerItem +'\r\n');
return innerQuery.reduce(function(innerP, inner, innerIndex){
return innerP.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});
}, Promise.resolve()).then(function() {
$csvText.append('\r\n\r\n');
});
});
}, Promise.resolve());
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 500) + 1));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
假设您有一个场景需要在页面的文本区域中创建 .csv 输出...
所以我有 2 个数组,我循环嵌套在另一个数组中。嵌套循环的结果是通过 ajax 调用的查询...我需要将 ajax 调用的结果附加到文本区域中。
我的问题是如何按照请求的顺序打印出结果(基本上是查询数组中的顺序)
//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery= ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');
//outter loop
$.each(outerQuery, function(outerIndex, outer){
//Print the row
$csvText.append('Row' + outer +'\r\n\r\n');
//Nested inner loop (that should execute in order regarless or the time of the api call)
innerQuery.reduce(function(innerCallback, inner, innerIndex){
return innerCallback.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});//end inner callback
},Promise.resolve());
});
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 1000) + 1));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
正如您在代码段中看到的结果 运行 非常奇怪 理想情况下,它们应该像这样打印:
RowA
1,2,3,4,5,6
RowB
1,2,3,4,5,6
RowC
1,2,3,4,5,6
.
.
.
我从
谢谢大家
您可以使用 .queue()
, .promise()
到 return 函数,顺序对应于数组中的索引
//example array to loop.
var outerQuery = ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery = ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
var $csvText = $('#some-text-area');
// create `"outerQuery"` queue
$csvText.queue("outerQuery", $.map(outerQuery, function(outer, index) {
return function(next) {
$(this).append((index > 0 ? '\r\n\r\n' : "")
+ 'Row' + outer + '\r\n\r\n')
// create `"innerQuery"` queue
.queue("innerQueue", $.map(innerQuery, function(inner, innerIndex) {
return function(_next) {
return GoogleAnalyticsAPI(inner).then(function(response) {
$csvText.append(response.column1 + ',');
// call `_next` function in `"innerQueue"`
}).then(_next);
}
})).dequeue("innerQueue").promise("innerQueue")
// call `next` function in `"outerQueue"`
// when all functions in current `innerIndex`
// of `innerQueue` array , `"innerQueue"` completes
.then(next)
}
})).dequeue("outerQuery");
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({
column1: val
});
}, Math.floor((Math.random() * 1000) + 1));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>
您可以继续使用在 .reduce()
循环中使用的相同逻辑,并将其应用于外部循环。此外,您可以使用普通 Javascript 概念进行同步。
这样做的关键是来自先前答案的内部 .reduce()
循环 returns 只有当内部循环中的所有链式异步操作完成时才会解决的承诺。您可以像这样使用该承诺来控制和同步外循环:
//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var innerQuery= ['1', '2', '3', '4', '5', '6'];
//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');
//outer loop
outerQuery.reduce(function(outerP, outerItem) {
return outerP.then(function() {
//Print the row
$csvText.append('Row' + outerItem +'\r\n');
return innerQuery.reduce(function(innerP, inner, innerIndex){
return innerP.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});
}, Promise.resolve()).then(function() {
$csvText.append('\r\n\r\n');
});
});
}, Promise.resolve());
function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 500) + 1));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="some-text-area" rows="20" cols="30"></textarea>