I need to wait for an ajax response inside a for loop. If I could I'd simply make a synchronous call instead of asynchronous, but I don't have that level of control: I'm using somebody else's API which in turn calls eBay's Javascript API.
我需要在for循环中等待ajax响应。如果我可以简单地进行同步调用而不是异步调用,但我没有那种控制级别:我正在使用其他人的API,而后者则调用eBay的Javascript API。
Below are my two functions, actually methods on the same closure/object, with categoryStack and categoryMap in scope for each. In essence I'm trying to recursively build up a map, though I want to use a stack for management, rather than true recursion.
下面是我的两个函数,实际上是同一个闭包/对象上的方法,每个函数的范围都有categoryStack和categoryMap。本质上,我试图递归地构建一个地图,虽然我想使用堆栈进行管理,而不是真正的递归。
I've tried a few variations on setInterval/setTimeout but I always get one of two results: one iteration of the loop, or an endless loop. Note that m_eBay.getChildCategories specifies the second of the two functions below as a callback, and I have confirmed that I am getting there successfully.
我在setInterval / setTimeout上尝试了一些变化,但我总是得到两个结果之一:循环的一次迭代,或无限循环。请注意,m_eBay.getChildCategories指定下面两个函数中的第二个作为回调,我已经确认我已成功到达那里。
function getChildCategories() {
categoryStack.push(-1);
while (categoryStack.length > 0) {
catId = categoryStack.pop();
m_eBay.getChildCategories({
'success':getChildCategoriesSuccess,
'failure':getChildCategoriesFailure},
{'siteid':0, 'CategoryID':catId, 'IncludeSelector':'ChildCategories'}
);
/*
use response from getChildCategoriesSuccess to reset categoryStack
*/
}
}
function getChildCategoriesSuccess(data){
if (data.categoryCount > 0) {
var categoryObjs = data.categoryArray.category;
for (var i=0, n=categoryObjs.length; i<n; i++) {
var catObj = categoryObjs[i];
if (catObj.categoryID != -1) { //skip root
categoryStack.push(catObj.categoryID);
categoryMap[catObj.categoryName] = catObj.categoryID;
}
}
}
}
1 个解决方案
#1
0
Using asynchronous ajax you need to do something like:
使用异步ajax你需要做类似的事情:
function getChildCategories(onload) {
var categoryStack = [-1];
function doNextOrFinish() {
if (categoryStack.length) {
m_eBay.getChildCategories({
'success': function(data) {
if (data.categoryCount > 0) {
var categoryObjs = data.categoryArray.category;
for (var i=0, n=categoryObjs.length; i<n; i++) {
var catObj = categoryObjs[i];
if (catObj.categoryID != -1) { //skip root
categoryStack.push(catObj.categoryID);
categoryMap[catObj.categoryName] = catObj.categoryID;
}
}
}
doNextOrFinish();
},
'failure':getChildCategoriesFailure},
{'siteid':0, 'CategoryID':categoryStack.shift(), 'IncludeSelector':'ChildCategories'}
);
} else {
if (onload) onload();
}
}
doNextOrFinish();
}
Still uses recursion though.
仍然使用递归。
Another solution to this problem is to use Arrows.
此问题的另一个解决方案是使用箭头。
#1
0
Using asynchronous ajax you need to do something like:
使用异步ajax你需要做类似的事情:
function getChildCategories(onload) {
var categoryStack = [-1];
function doNextOrFinish() {
if (categoryStack.length) {
m_eBay.getChildCategories({
'success': function(data) {
if (data.categoryCount > 0) {
var categoryObjs = data.categoryArray.category;
for (var i=0, n=categoryObjs.length; i<n; i++) {
var catObj = categoryObjs[i];
if (catObj.categoryID != -1) { //skip root
categoryStack.push(catObj.categoryID);
categoryMap[catObj.categoryName] = catObj.categoryID;
}
}
}
doNextOrFinish();
},
'failure':getChildCategoriesFailure},
{'siteid':0, 'CategoryID':categoryStack.shift(), 'IncludeSelector':'ChildCategories'}
);
} else {
if (onload) onload();
}
}
doNextOrFinish();
}
Still uses recursion though.
仍然使用递归。
Another solution to this problem is to use Arrows.
此问题的另一个解决方案是使用箭头。