鍍金池/ 問(wèn)答/HTML/ 關(guān)于《你不知道的JavaScript(中卷)》中“回調(diào)”章節(jié)中的案例的一個(gè)疑惑(

關(guān)于《你不知道的JavaScript(中卷)》中“回調(diào)”章節(jié)中的案例的一個(gè)疑惑(setTimeout()相關(guān))

題目描述

setTimeout() 內(nèi)的程序提前運(yùn)行。按照正常的情況,不是應(yīng)該在當(dāng)前 stack 內(nèi)全部執(zhí)行完成后才執(zhí)行,setTimeout() 函數(shù)的嗎?

題目來(lái)源及自己的思路

《你不知道的JavaScript(中卷)》的書(shū)中的案例改寫(xiě)而來(lái),其實(shí)我本身這個(gè)案例了解不夠透徹

相關(guān)代碼

function asyncify(fn) {
      var orig_fn = fn,
          intv = setTimeout(function () {
                    console.log('異步1')
                    intv = null;
                    if (fn) fn();
                 }, 0);
      console.log('Wai intv:'+intv);
      fn = null;
      return function () {
        console.log('異步2')   
        console.log('Nei intv:'+intv);
        if (intv) {
          fn = orig_fn.bind.apply(
            orig_fn,
            [this].concat([].slice.call(arguments))  
          );
        } else {
          console.log('異步3')
          orig_fn.apply(this, arguments); 
        }
      };
    }
    function result(data) {
      console.log(a); 
    }

    var a = 0;
    var b = setTimeout(asyncify(result),100);
 
    a++;
    console.log('end');

你期待的結(jié)果是什么?實(shí)際看到的錯(cuò)誤信息又是什么?

接待的結(jié)果是:按照 setTimeout() 內(nèi)函數(shù)執(zhí)行時(shí)間,應(yīng)該是排在當(dāng)前 stack 內(nèi)的函數(shù)執(zhí)行完成后。

所以,我認(rèn)為,應(yīng)該先輸出“end”, 后輸出“Wai intv:1”

實(shí)際運(yùn)行結(jié)果:

圖片描述

回答
編輯回答
夕顏

你這樣想
setTimeout(fn, 100)
fn是定義的一個(gè)函數(shù),它是隔了100毫秒才執(zhí)行
但是如果你寫(xiě)成 setTimeout(fn(), 100) 這是函數(shù)自調(diào)用,fn函數(shù)會(huì)立即執(zhí)行,
隔了100毫秒,才會(huì)執(zhí)行fn return后的函數(shù)

2017年8月11日 23:26
編輯回答
陌顏

先執(zhí)行了asyncify(result),定時(shí)器那一步分解一下,你應(yīng)該就能看懂了。

var a = 0;
var timeoutFn = asyncify(result);
var b = setTimeout(timeoutFn,100);

a++;
console.log('end');
2017年6月26日 21:37
編輯回答
雅痞

因?yàn)?code>asyncify(result)先執(zhí)行了。

2018年8月11日 22:43