2017-08-24 115 views
-1

我在節點是新的,所以下面的代碼的行爲是不明確的對我說:的Node.js:()setImmediate後http.request()觸發

function step(iteration) { 
    if (iteration === 10) return; 

    process.nextTick(() => { 
    step(iteration + 1); // Recursive call from nextTick handler. 
    console.log(`nextTick iteration: ${iteration}`);  
    }); 

    http.request({hostname: '127.0.0.1', port: 5000}, (response) => { 
    console.log("here !"); 
    }).end(); 

    setImmediate(() => { 
    console.log(`setImmediate iteration: ${iteration}`);  
    }); 
} 
step(0); 

OUTPUT:

nextTick iteration: 0 
... 
nextTick iteration: 9 
setImmediate iteration: 0 
... 
setImmediate iteration: 9 
here ! 
here ! 
here ! 
here ! 
here ! 
here ! 
here ! 
here ! 
here ! 
here ! 

問題是:

1)爲什麼http.request()回調是在setImmediate()之後觸發的?我不明白,爲什麼setImmediate()通常被稱爲:它的回調是在循環中註冊的。但正如文件所述,setImmediate()檢查階段,應該在事件循環後處理輪詢一。如果我理解正確,http.request()nextTick()應該是輪詢階段;

2)但是如果http.request()沒有在輪詢中處理,它發生在什麼階段?特別是考慮到它在setImmediate()之後有效。

我的Node.js版本是6.11.2。預先感謝您的解釋。

+0

它稍後記錄它,因爲它正在等待*響應* – 2017-08-24 22:31:51

回答

-1

回答您的問題:

  1. http.request()setImmediate()之前調用。但是,http.request是異步的。在你的情況下,直到請求解析後纔會運行回調。這意味着雖然它被稱爲第一個,但回調不會記錄任何事情,直到稍後的時間點 - 並且該點在setImmediate()解決之後。
  2. 儘管setImmediate將它的回調按其排隊順序排隊執行,但它們仍然能夠在請求返回前解析。

爲了處理爲了你的腳步,考慮移動nextTick內容的回調中的請求:

function step(iteration) { 
    if (iteration === 10) return; 

    http.request({hostname: '127.0.0.1', port: 8000}, (response) => { 
    console.log("here !"); 

    step(iteration + 1); // Recursive call from nextTick handler. 

    console.log(`nextTick iteration: ${iteration}`);  
    }).end(); 

    setImmediate(() => { 
    console.log(`setImmediate iteration: ${iteration}`);  
    }); 
} 
step(0); 

在該片段中,我已經去除了nextTick,雖然你如果需要可以安全地將其添加到回調中。

+0

_儘管先調用'http.request()',回調不記錄任何內容,直到稍後的時間點 - 並且該點位於' setImmediate()'已經解決了._ - 你能給出一個關於文檔的鏈接嗎? –

+0

因爲我讀過[反面](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#poll):_如果輪詢queue_(我認爲,http。 request()'在該隊列中)_is不爲空​​,則事件循環將遍歷其同步執行它的回調隊列。如果腳本已由setImmediate()調度,則事件循環將結束輪詢階段並繼續執行這些預定腳本的檢查階段。因此,我建議早期觸發請求的回調,即setImmediate是一個。 –

+0

您鏈接到的文檔是正確的,但它不適用於傳遞給'.request()'的回調。在https://nodejs.org/api/http.html#http_http_request_options_callback下,它注意到:「可選的回調參數將作爲'響應'事件的一次性偵聽器添加。」 即使通過'。request()'正在被立即執行,響應被異步接收。你可以看到這個,如果你聽到'request'的即時回調,比如'request.on('socket',...)',它似乎是同步的,並且記錄在'setImmediate'之前。 – Hans

相關問題