暂停大量 AJAX 调用,多个数据集
Pausing Large number of AJAX calls, multiple data sets
我正在尝试创建一个 Web 实用程序,它采用多个大型数据集并进行 ajax 调用来处理它们并将它们索引到 table 中以供搜索。基本上,数据会被分解成5个数据集,但为了简单起见,我将样本数据缩减为两组(基本都是多维数组)。
- 库存物品
- 系统
为了简单起见,我们再说一遍,每个数据集都有 3 个项目。
JAVASCRIPT 第 1 部分
var inventory = [
{"id": "1","title": "0002\/840","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"}
];
var systems = [
{"id": "28","title": "System 1","type": "system"},
{"id": "54","title": "System 2","type": "system"},
{"id": "76","title": "System 3","type": "system"}
];
它的工作方式应该是代码命中第一个库存项目,根据它进行 ajax 调用,等待响应,然后移动到第二个项目。它一遍又一遍地这样做,直到它到达最后一个项目,此时,它移动到下一个数据集(系统),然后通过这些数据集。
现在,我的这个工作得很好。您可以在下面的 CodePen link 中看到一个功能齐全的示例。此版本的 JS 代码内置了一个小延迟,以更好地演示该问题。
现在有人要求我添加一个 pause/unpause 功能。对于如何在不冻结浏览器的情况下停止它,我有点不知所措,更重要的是,如何在正确数据集中的正确位置恢复我离开的地方。
我尝试添加一个可以打开和关闭的 paused
布尔变量,然后在我的函数中添加一个循环,它只等待 paused
变量变为 false
。这显然捆绑了浏览器 window.
任何人都可以阐明我如何能够在不破坏浏览器的情况下进行暂停和取消暂停吗?
提前致谢。
剩余 JAVASCRIPT 第 2 部分
var paused = false;
function PauseIndexing() {
//paused = true;
}
function BeginIndexing() {
updateItems(inventory, 'inventory', 0, function () {
//This gets called when inventory is done
updateItems(systems, 'systems', 0, function () {
alert("Inventory and Systems Imported");
});
});
}
function updateItems(items, type, x, callback) {
/* This causes complete freeze as expected*/
//while (paused) {}
var item_count = items.length;
$.post('', {
item: items[x],
type: type
}, function () {
x++;
if (x == item_count) {
callback();
} else {
updateItems(items, type, x, callback);
}
});
}
应该这样做:
function PauseIndexing(pause) {
paused = pause;
}
function updateItems(items, type, x, callback) {
if (paused) {
return setTimeout(updateItems, 100, items, type, x, callback);
}
var item_count = items.length;
$.post('', {
item: items[x],
type: type
}, function () {
x++;
if (x == item_count) {
callback();
} else {
updateItems(items, type, x, callback);
}
});
}
这里你必须使用pausedAt = x
保持进度状态,然后从你离开的地方继续。下面是更改后的代码片段和工作示例 link.
function BeginIndexing(x) {
updateItems(inventory, 'inventory', x, function () {
pausedAt = x = 0;
updateItems(systems, 'systems', x, function () {
alert("Inventory and Systems Imported");
});
});
}
function ContinueIndexing(){
paused = false;
console.log(pausedAt)
BeginIndexing(pausedAt);
}
function updateItems(items, type, x, callback) {
if(paused){
pausedAt = x;
return
}
否则检查下面的结果
var paused = false;
var pausedAt = 0;
var inventory = [
{"id": "1","title": "0002\/840","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"}
];
var systems = [
{"id": "28","title": "System 1","type": "system"},
{"id": "54","title": "System 2","type": "system"},
{"id": "76","title": "System 3","type": "system"}
];
function PauseIndexing() {
paused = true;
//pausedAt = x;
}
function BeginIndexing(x) {
updateItems(inventory, 'inventory', x, function () {
pausedAt = x = 0;
updateItems(systems, 'systems', x, function () {
alert("Inventory and Systems Imported");
});
});
}
function ContinueIndexing(){
paused = false;
console.log(pausedAt)
BeginIndexing(pausedAt);
}
function updateItems(items, type, x, callback) {
if(paused){
pausedAt = x;
return
}
/* This causes complete freeze as expected*/
/*
while (paused) {
}
*/
var item_count = items.length;
setTimeout(function(){
$.post('http://www.geonames.org/countries/', {
item: items[x],
type: type
}, function () {
x++;
console.log(x);
if (x == item_count) {
updateBar(item_count, 100, type);
updateText("<span style='color:#090;'>Done!</span>", type);
callback();
} else {
var perc = Math.round((x / item_count) * 100);
updateBar(x, perc, type);
updateItems(items, type, x, callback);
}
});
}, 500);
}
function updateText(val, type) {
$('small.' + type + '_name').html(val);
}
function updateBar(x, perc, type) {
$('.progress.' + type + ' .progress-bar')
.attr('aria-valuenow', perc)
.css('width', perc + '%')
.html(x + ' (' + perc + '%)');
}
function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
.progress{background:#333;}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn btn-lg btn-success" onclick="BeginIndexing(0);">Start!</div>
<div class="btn btn-lg btn-primary" onclick="PauseIndexing(true);">Pause</div>
<div class="btn btn-lg btn-primary" onclick="ContinueIndexing(false);">Continue</div>
<div class="panel">
<div class="panel-body">
<h2>9 Inventory Items</h2>
<small class="inventory_name">Pending....</small>
<div class="progress inventory">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
0 (0.00%)
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-body">
<h2>3 Systems</h2>
<small class="systems_name">Pending....</small>
<div class="progress systems">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
0 (0.00%)
</div>
</div>
</div>
</div>
我正在尝试创建一个 Web 实用程序,它采用多个大型数据集并进行 ajax 调用来处理它们并将它们索引到 table 中以供搜索。基本上,数据会被分解成5个数据集,但为了简单起见,我将样本数据缩减为两组(基本都是多维数组)。
- 库存物品
- 系统
为了简单起见,我们再说一遍,每个数据集都有 3 个项目。
JAVASCRIPT 第 1 部分
var inventory = [
{"id": "1","title": "0002\/840","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"}
];
var systems = [
{"id": "28","title": "System 1","type": "system"},
{"id": "54","title": "System 2","type": "system"},
{"id": "76","title": "System 3","type": "system"}
];
它的工作方式应该是代码命中第一个库存项目,根据它进行 ajax 调用,等待响应,然后移动到第二个项目。它一遍又一遍地这样做,直到它到达最后一个项目,此时,它移动到下一个数据集(系统),然后通过这些数据集。
现在,我的这个工作得很好。您可以在下面的 CodePen link 中看到一个功能齐全的示例。此版本的 JS 代码内置了一个小延迟,以更好地演示该问题。
现在有人要求我添加一个 pause/unpause 功能。对于如何在不冻结浏览器的情况下停止它,我有点不知所措,更重要的是,如何在正确数据集中的正确位置恢复我离开的地方。
我尝试添加一个可以打开和关闭的 paused
布尔变量,然后在我的函数中添加一个循环,它只等待 paused
变量变为 false
。这显然捆绑了浏览器 window.
任何人都可以阐明我如何能够在不破坏浏览器的情况下进行暂停和取消暂停吗?
提前致谢。
剩余 JAVASCRIPT 第 2 部分
var paused = false;
function PauseIndexing() {
//paused = true;
}
function BeginIndexing() {
updateItems(inventory, 'inventory', 0, function () {
//This gets called when inventory is done
updateItems(systems, 'systems', 0, function () {
alert("Inventory and Systems Imported");
});
});
}
function updateItems(items, type, x, callback) {
/* This causes complete freeze as expected*/
//while (paused) {}
var item_count = items.length;
$.post('', {
item: items[x],
type: type
}, function () {
x++;
if (x == item_count) {
callback();
} else {
updateItems(items, type, x, callback);
}
});
}
应该这样做:
function PauseIndexing(pause) {
paused = pause;
}
function updateItems(items, type, x, callback) {
if (paused) {
return setTimeout(updateItems, 100, items, type, x, callback);
}
var item_count = items.length;
$.post('', {
item: items[x],
type: type
}, function () {
x++;
if (x == item_count) {
callback();
} else {
updateItems(items, type, x, callback);
}
});
}
这里你必须使用pausedAt = x
保持进度状态,然后从你离开的地方继续。下面是更改后的代码片段和工作示例 link.
function BeginIndexing(x) {
updateItems(inventory, 'inventory', x, function () {
pausedAt = x = 0;
updateItems(systems, 'systems', x, function () {
alert("Inventory and Systems Imported");
});
});
}
function ContinueIndexing(){
paused = false;
console.log(pausedAt)
BeginIndexing(pausedAt);
}
function updateItems(items, type, x, callback) {
if(paused){
pausedAt = x;
return
}
否则检查下面的结果
var paused = false;
var pausedAt = 0;
var inventory = [
{"id": "1","title": "0002\/840","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"},
{"id": "2","title": "0002\/841","type": "inventory"},
{"id": "3","title": "0002\/842","type": "inventory"}
];
var systems = [
{"id": "28","title": "System 1","type": "system"},
{"id": "54","title": "System 2","type": "system"},
{"id": "76","title": "System 3","type": "system"}
];
function PauseIndexing() {
paused = true;
//pausedAt = x;
}
function BeginIndexing(x) {
updateItems(inventory, 'inventory', x, function () {
pausedAt = x = 0;
updateItems(systems, 'systems', x, function () {
alert("Inventory and Systems Imported");
});
});
}
function ContinueIndexing(){
paused = false;
console.log(pausedAt)
BeginIndexing(pausedAt);
}
function updateItems(items, type, x, callback) {
if(paused){
pausedAt = x;
return
}
/* This causes complete freeze as expected*/
/*
while (paused) {
}
*/
var item_count = items.length;
setTimeout(function(){
$.post('http://www.geonames.org/countries/', {
item: items[x],
type: type
}, function () {
x++;
console.log(x);
if (x == item_count) {
updateBar(item_count, 100, type);
updateText("<span style='color:#090;'>Done!</span>", type);
callback();
} else {
var perc = Math.round((x / item_count) * 100);
updateBar(x, perc, type);
updateItems(items, type, x, callback);
}
});
}, 500);
}
function updateText(val, type) {
$('small.' + type + '_name').html(val);
}
function updateBar(x, perc, type) {
$('.progress.' + type + ' .progress-bar')
.attr('aria-valuenow', perc)
.css('width', perc + '%')
.html(x + ' (' + perc + '%)');
}
function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
.progress{background:#333;}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn btn-lg btn-success" onclick="BeginIndexing(0);">Start!</div>
<div class="btn btn-lg btn-primary" onclick="PauseIndexing(true);">Pause</div>
<div class="btn btn-lg btn-primary" onclick="ContinueIndexing(false);">Continue</div>
<div class="panel">
<div class="panel-body">
<h2>9 Inventory Items</h2>
<small class="inventory_name">Pending....</small>
<div class="progress inventory">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
0 (0.00%)
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-body">
<h2>3 Systems</h2>
<small class="systems_name">Pending....</small>
<div class="progress systems">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
0 (0.00%)
</div>
</div>
</div>
</div>