Javascript代码无序运行

时间:2018-04-05 15:23:19

标签: javascript

当我在等待使用jsPDF创建pdf时,我正在尝试运行加载覆盖,但是我尝试这样做,不运行覆盖功能。我试过使用回调函数,但我想我可能会错误地使用它。加载程序更改背景的不透明度并显示隐藏的div。

我最初在exporttopdf函数的主体中调用了loader函数但是这没有用,所以我把它改成了实际的loader函数中的回调函数。我迷路了 - 请帮忙。

我创建了一个jsfiddle,它是我的代码的简化版本,用于显示问题。警报开始,样式更改无法启动。 https://jsfiddle.net/13pkp1xn/295/

以下是实际代码

在按钮上激活HTML

<div class=sidebar>
      <button onclick='loader("start","exporting",function(){exporttopdf();})' class="sidebarbutton">Export</button>
</div>

JAVASCRIPT

function loader(action, text, callback) {

     if (action == "start") {
       document.getElementById("contentbox").style.opacity = 0.4;
       document.getElementById("loadertext").innerHTML = text;
       document.getElementById("loader").style.display = "block";
     } else {
       document.getElementById("contentbox").style.opacity = 1
       document.getElementById("loadertext").innerHTML = "";;
       document.getElementById("loader").style.display = "none";
    }

   if (typeof callback === "function") {
      callback();
   }
}

function exporttopdf() {

  var runnumber = getUrlVars()["runnumber"];
  var doc = new jsPDF();


  var canvases = document.getElementsByClassName("canvas");
  for (var i = 0; i < canvases.length; i++) {

    currentcanvas = canvases[i];
    url_base64jp = currentcanvas.toDataURL("image/jpg");
    doc.text(20, 20, currentcanvas.id);
    doc.addImage(url_base64jp, 'png', 15, 40, 180, 160, null, 'FAST');
    doc.addPage();
  }
  doc.save(runnumber + '.pdf')
  loader("stop");

}

3 个答案:

答案 0 :(得分:0)

使用setTimeout函数尝试这样:

if (typeof callback === "function") {
   window.setTimeout(callback, 1);
}

通过在不同的“执行上下文”中运行回调,您会感觉两个操作并行执行。

请参阅更新的小提琴:https://jsfiddle.net/dsLazrc4/

答案 1 :(得分:0)

我按照以下方式编辑了你的小提琴:

JavaScript代码:

function loader(text, callback) 
{

    document.getElementById("contentbox").style.background = "grey";
    document.getElementById("loadertext").innerHTML = text;
    document.getElementById("loader").style.display = "block";

  if (typeof callback === "function") {
    callback();
  }
}

var exportToPdf = function exporttopdf() {
  alert("exporting");

  setTimeout(function()
  {
    document.getElementById("contentbox").style.background = "pink";
    document.getElementById("loadertext").innerHTML = "";
    document.getElementById("loader").style.display = "none";
  },5000)

}

点击加载程序按钮上的事件:

 <input type='button' value='Just loader' onclick='loader("loading",exportToPdf)'>

点击&#34; Just loader&#34;按钮现在,它将应用更改,然后在处理警报后5秒后恢复。

答案 2 :(得分:0)

您在小提琴中遇到的问题是,在您的javascript代码退出之前,浏览器不会重新绘制页面。 alert暂停执行,直到用户点击ok,因此当警报框可见时,您仍然卡在exporttopdf功能中。

延迟视觉更新并不是这样的问题所导致的唯一问题。实际上,在您的javascript代码退出之前,浏览器根本不会任何 。它会完全没有反应。

浏览器中的JS使用异步编程来解决这类问题。简而言之,您必须做的是为浏览器提供某种事件处理程序并让您的函数返回。这样,浏览器就可以完成它的工作,然后在需要运行更多JS时调用事件处理程序。

回调函数是建模异步编程的常用方法,但没有任何关于它们本身异步。你正在做的只是简单地调用回调函数同步,它永远不会给浏览器重绘的机会。

Marcus的回答有效,因为window.setTimeout异步操作。它基本上告诉浏览器,“嘿,我现在已经完成了,但是在一毫秒内我还需要做其他事情。”您的代码退出,浏览器重绘,然后 - 因为至少有一毫秒几乎肯定已经通过 - 它开始运行您的回调。

如果您想成为一名称职的网络开发人员,了解这一点绝对至关重要。有了这种理解,也应该实现为什么在创建大文件时客户端这样的pdf生成可能会成为问题。如果jsPDF花费足够长的时间以至于您觉得需要向用户显示一些加载指示,那么您可能不应该在客户端制作这些pdf,因为即使您正在显示消息,您也可以在创建pdf时仍然会导致令人沮丧的浏览器锁定。

如果您确实必须在客户端执行此操作,您可能需要考虑使用web worker的可能性。不幸的是,这是一项相当新的技术,因此您可能无法在旧版浏览器中使用它。