Javascript 如何向长时间运行的函数添加预加载程序

Javascript 如何向长时间运行的函数添加预加载程序,javascript,jquery,Javascript,Jquery,我开发了一个自定义html页面,其中包含有关本地计算机上已安装证书的信息。我通过crypto provider api获取证书的信息,然后过滤返回的证书,并设置一些限制(颁发者、CommonName等)。这是我的函数loadCertificates的工作。我在点击按钮时显示结果。但是loadCertificates需要几秒钟的时间,我想在loadCertificates之前显示预加载程序,然后隐藏: $("#select__cert-btn").click(function ()

我开发了一个自定义html页面,其中包含有关本地计算机上已安装证书的信息。我通过crypto provider api获取证书的信息,然后过滤返回的证书,并设置一些限制(颁发者、CommonName等)。这是我的函数
loadCertificates
的工作。我在点击按钮时显示结果。但是
loadCertificates
需要几秒钟的时间,我想在
loadCertificates
之前显示预加载程序,然后隐藏:

        $("#select__cert-btn").click(function () {
            showPreloader();
            var certificates = loadCertificates(restrictions);
            hidePreloader();
            showCerificates(certificates);
        });
函数
showPreloader
hidePreloader
仅将具有gif背景的div添加/删除到具有证书信息的容器中。但当我点击按钮时,我的页面似乎冻结了,只有几秒钟后才会显示结果(没有显示我的预加载程序)。但是在调试模式下,在运行
loadCertificates
之前,会将预加载程序添加到html中,但它不可见

早期我从来没有遇到过同样的问题,但它看起来像是
loadCertificates
block主线程,但是如果我是对的,为什么
showpreload
不能正确工作呢


如何解决我的问题?

如果loadCertificates函数通过ajax调用端点,则只需添加一个html区域,该区域将用gif图像隐藏/显示(加载):


我将尝试使用承诺,以便loadCertificates在不锁定主线程的情况下异步运行

试试这个:

$("#select__cert-btn").click(function () {
    showPreloader();
    var certificates = new Promise(function(resolve, reject) {
       loadCertificates(restrictions);
       resolve();
    });
    certificates.then(function(result) {
        hidePreloader();
        showCerificates(certificates);
    });
});

我不使用AjaxAPI,那个么你们是如何调用你们的API的呢?API和安装在浏览器中的插件相连。我只使用一个函数plugin.Store.Open(),如果loadCertificates()所做的是同步的,那么您的方法应该可以工作。如果不是,则需要在操作(loadCertificates)完成时触发的回调中调用hidePreloader()方法。不幸的是,我使用IE 11:(如果
loadCertificates
是异步的,则可以尝试此操作,除非函数返回承诺或回调,否则您无法等待其结果。看起来
loadCertificates
不是异步的。您需要给浏览器时间更新预加载程序。在showPreload()之后包装所有代码)在一个
setTimeout
中允许浏览器更新。我昨天读到了一个副本,我将尝试查找,因此没有完整的答案。这是否回答了您的问题?@freedomn-m,它没有帮助。当我使用
loadCertificates
gif blocked by“blocked”到达行时,我假设您的意思是:“gif现在显示,但没有动画”-这就是锁定浏览器的浏览器/插件,除了更改
loadCertificates
的工作方式之外,您别无选择。
var ajaxLoading = $('#ajaxLoading');
//add a spinner to every ajax call
    $(document).ajaxStart(function () {
        ajaxLoading.show();
    });
    $(document).ajaxStop(function () {
        ajaxLoading.hide();
    });
$("#select__cert-btn").click(function () {
    showPreloader();
    var certificates = new Promise(function(resolve, reject) {
       loadCertificates(restrictions);
       resolve();
    });
    certificates.then(function(result) {
        hidePreloader();
        showCerificates(certificates);
    });
});