在下面的 jQuery 代码中,我想显示一个微调器,直到 for 循环完成 但由于 javascript 的异步特性,它会在 for 循环结束之前执行最后一行并隐藏微调器。
jQuery 中有类似回调() 的东西吗?谢谢
$('#ajaxSpinnerImage').hide();
$('#bulkUploadButton').on('click',function(){
$('#ajaxSpinnerImage').show();
for(var i=0; i < casNumbersArray.length; i++) {
// Long running operation
}
$('#ajaxSpinnerImage').hide(); // How to wait till forloop ends?
});
更新:-
for循环中不涉及任何API。只是一个本地数组迭代,需要更长的时间,也许一分钟。这是带有 jQuery 的普通 JS
一般来说,您应该使用 WebWorkers,但以下内容可能会有所帮助:
$('#ajaxSpinnerImage').hide();
$('#bulkUploadButton').on('click',function(){
$('#ajaxSpinnerImage').show();
setTimeout(work, 1);
function work() {
for(var i=0; i < casNumbersArray.length; i++) {
// Long running operation
}
$('#ajaxSpinnerImage').hide();
}
});
尝试将 for 循环分成几个部分。否则,我认为您的 UI 可能在此 for 循环期间没有响应。
这是使用条件的非常简单的方法。如果你有竞赛条件,你可以使用 promises 来解决所有完成,或者你可以使用 jquery deferred object
如果用户界面在处理长计算时出现滞后,您应该使用 web-workers 来缓解主线程
var casNumbersArray = [0,1,2,3,4,5];
$('#ajaxSpinnerImage').hide();
function longOperation (i) {
console.log(i);
if (i == casNumbersArray.length - 1) {
$('#ajaxSpinnerImage').hide();
console.log('finished');
}
}
$('#bulkUploadButton').on('click',function(){
console.log('start');
$('#ajaxSpinnerImage').show();
for(var i=0; i < casNumbersArray.length; i++) {
setTimeout(longOperation.bind(this, i), i*1000);
// perform one operation per second
}
});
#ajaxSpinnerImage {
animation: rotate 1s linear infinite;
display: inline-block;
width: 15px; height: 15px;
font-size: 15px;
border: 1px solid black;
border-radius: 50%;
padding: 4px;
}
@keyframes rotate {
0% {transform: rotate(0)}
100% {transform: rotate(360deg)}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="bulkUploadButton">Start long operation</button>
<div id="ajaxSpinnerImage">ⓞ</div>
这可能不是最有效的解决方案,但请尝试 jQuery 的 When
也正如其他人所建议的,如果您有一个长时间运行的线程,为了不冻结 UI 并降低用户体验,请使用 Web Workers
$('#ajaxSpinnerImage').hide();
$('#bulkUploadButton').on('click',function(){
$('#ajaxSpinnerImage').show();
$.when(longRunningOperation()).done(function( ) {
$('#ajaxSpinnerImage').hide(); // How to wait till forloop ends?
});
function longRunningOperation() {
for(var i=0; i < casNumbersArray.length; i++) {
// Long running operation
}
}
});
我们可以稍微更改代码以并行运行异步操作:
async function processArray(array) {
// map array to promises
const promises = array.map(delayedLog);
// wait until all promises are resolved
await Promise.all(promises);
console.log('Done!');
}
此代码最后一行不再可用 将并行运行许多delayLog任务。但要小心非常大的数组(太多并行任务对于 CPU 或内存来说可能太重)。
也不要将这里的“并行”与真正的线程和并行混淆。该代码不能保证执行的真正并行性。这取决于您的项目功能(本演示中的delayedLog)。网络请求、网络工作者和其他一些任务可以并行执行。
您似乎正在编程上下文中运行循环,并希望确保最后一行代码立即执行,而不需要等待循环完成。与friday night funkin类似,时机和节拍同步对于成功至关重要;确保你的代码逻辑也正确!优化您的循环以允许无缝执行重要任务。