超时未按预期工作

时间:2017-08-29 08:43:21

标签: javascript settimeout

public void downloadallimage()
    { 
        DataTable dtpic;

             dtpic = DBData.getDataTable(DBData.DataPath, "select * from Table");

       ZipFile zip = new ZipFile();

        foreach (DataRow dr in dtpic.Rows)
        {

            zip.AddEntry(dr["UploadedFileName"].ToString(), (byte[])dr["Photo1"]);

        }

        var zipMs = new MemoryStream();
        zip.Save(zipMs);
        byte[] fileData = zipMs.GetBuffer();
        zipMs.Seek(0, SeekOrigin.Begin);
        zipMs.Flush();
        Response.Clear();
        Response.AddHeader("content-disposition", "attachment;filename=docs.zip ");
        Response.ContentType = "application/zip";
        Response.BinaryWrite(fileData);
        Response.End();
    }

在这段代码中,我试图在0.5秒后在控制台中打印 Timeout ,并且有一个while循环在大约2秒的时间后终止,我通过记录所花费的时间来显示。我希望 Timeout 首先打印,因为它在0.5秒内完成,并且 whileloop breaking 应打印,这需要更多时间,但它首先打印 whileloop打破 然后转到 超时 ...任何人都可以解释堆栈跟踪或流程这段代码。

3 个答案:

答案 0 :(得分:2)

首先,我不会说英语。 但我想帮助你

浏览器是单线程事件队列。 如果第一个任务正在运行,那么将保留所有事件

查看您的代码

您声明了setTimeout 但是,此setTimeout以0.5秒

运行

但是你不能在0.5秒后执行setTimeout 因为whileloop在单线程浏览器中只有一个线程

我为你准备了一个链接

Wrestling with the Browser Event Queue

Concurrency model and Event Loop

答案 1 :(得分:0)

正如@RobG评论的那样 - " Javascript是单线程的。超时无法运行,直到while循环结束。"

但是,如果您想首先打印 超时 ,然后在代码中打开 whileloop ,请尝试以下操作 - -



console.time("Time");
var i=0;
//setTimeout(function(){console.log("Timeout...")},500);
setTimeout(console.log("Timeout..."),500);

while(true){
  if(i==1000000000){
    console.timeEnd("Time");
    console.log("whileloop breaking...");
    break;
  }
  else{i++;}
}




我刚从function(){}移除了setTimeout ..

答案 2 :(得分:0)

这是查看运行上述代码时发生的最佳方式:

http://latentflip.com/loupe/?code=Y29uc29sZS50aW1lKCJUaW1lIik7DQp2YXIgaT0wOw0Kc2V0VGltZW91dChmdW5jdGlvbigpe2NvbnNvbGUubG9nKCJUaW1lb3V0Li4uIil9LDUwMCk7DQoNCndoaWxlKHRydWUpew0KICBpZihpPT0xMDAwMDAwMDAwKXsNCiAgICBjb25zb2xlLnRpbWVFbmQoIlRpbWUiKTsNCiAgICBjb25zb2xlLmxvZygid2hpbGVsb29wIGJyZWFraW5nLi4uIik7DQogICAgYnJlYWs7DQogIH0NCiAgZWxzZXtpKys7fQ0KfQ0KIA%3D%3D!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D

让我们了解代码中发生的事情

    console.time("Time");
        var i=0;
        //here a callback is registered and should be called when timer expires
        setTimeout(function(){console.log("Timeout...")},500);

        //since settimeout is async in nature, main thread continues 
    //to execute new line of code i.e. while loop
        // After 500 ms when timer expires, it puts the callback in event queue, 
    // the callback will be executed as soon as it sees the main thread free, but since 
//while loop is running on main thread for 2sec, the main thread will be free //only after 2 sec (or while loop) finishes.
        while(true){
          if(i==1000000000){
            console.timeEnd("Time");
            console.log("whileloop breaking...");
            break;
          }
          else{i++;}
        }
        // as there is no code to be executed now, main thread takes new task from 
        // event Queue, in this case the new task is callback from settimeout.

我希望这有助于您了解settimeout