2016-11-08 51 views
3

在Node.js中(我是新手)我正在嘗試在收到響應後執行一系列任務。但是,我想盡可能快地做出響應。我不需要將這些任務的結果返回給客戶端,所以我試圖立即返回響應。發送回覆並繼續執行Express |任務Node.js

我當前實現大致是:

var requestTime = Date.now; 

app.post('/messages', function (req, res) { 
    console.log("received request"); 

    // handle the response 
    var body = res.body; 
    res.send('Success'); 
    res.end(); 
    console.log("sent response"); 

    performComplexTasks(body) 
}) 

function performComplexTasks(body){ 
    // perform data with body data here; 
    console.log("finished tasks:", Date.now()-requestTime, "ms"); 
} 

// -------LOG----------- 
// received request 
// POST /api/messages 200 3.685 ms - 59 
// sent response 
// finished tasks: 2500ms 

客戶端發出請求似乎掛起,直到performComplexTasks()完成。 (POST在3.685ms內完成,但響應需要2500ms才能完成。)

有沒有辦法立即發送響應並完成其他任務而無需客戶端等待/掛起? (在我的情況下,客戶端不能進行多個API調用。)

+0

你應該工作得很好嗎?只要響應在服務器上結束,那麼之後會發生什麼情況不應該影響瀏覽器。 – adeneo

+0

@adeneo我已經在本地使用CURL測試了它,並且響應需要在「200-15000ms」之間。當我註釋掉'performComplexTasks(body)'時,響應花費大約10ms。所有其他API端點(沒有長時間任務)似乎更快。這可能是因爲一個獨立的問題(即我的服務器CPU使用率,而不是正確處理'req','res')?如果是這樣,你有什麼建議我應該開始調查? –

+0

@adeneo另外,萬一它很重要,這個端點將被另一個服務器(而不是瀏覽器)調用。 –

回答

1

我說得對,您試圖在performComplexTasks中執行CPU密集型作業嗎?如果是這樣,那麼事件循環被該任務鎖定,並且新的請求正在等待,直到作業完成。

在node.js中執行與http服務器相同的進程中的「複雜」任務是不好的做法。考慮使用後臺工作人員,隊列或類似的東西。

請參見本主題的詳細信息:Node.js and CPU intensive requests

+0

這是真的,但OP的代碼應該結束響應,然後進行阻塞工作,這樣新的請求將不得不等待等等,它不應該阻止當前已經收到響應的請求。 – adeneo

+0

@No Danger當您剛開始使用快遞應用程序時,第一次請求POST /消息怎麼樣?它運行速度快嗎? – teq

+0

@不危險你確定其他端點不受影響嗎?你打電話給POST /消息之前和之後你有沒有試過打電話給他們?還要確保performComplexTasks函數沒有任何「全局」變量/鎖(在請求之間共享) – teq

0

如果你的工作是不是超級CPU-激烈,你能容忍主服務器的線程上的一些工作,然後只用等待打破執行,以便請求可以正確發送。您可以使用setTimeoutawait

var requestTime = Date.now; 

app.post('/messages', async function (req, res) { 
    console.log("received request"); 

    // handle the response 
    var body = res.body; 
    res.status(200).send({ success: true }); 
    console.log("sent response"); 

    // Method 1: 
    await performComplexTasks(body) 

    // Method 2: 
    setTimeout(() => performComplexTasks(body), 0); 
}) 

async function performComplexTasks(body){ 
    // perform data with body data here; 
    console.log("finished tasks:", Date.now()-requestTime, "ms"); 
}