[英]Asynchronous express handlers with fork
考慮以下快遞程序
const express = require("express");
const { fork } = require('child_process');
const API_PORT = 3001
const app = express()
app.listen(API_PORT, () => console.log(`Listening on port ${API_PORT}`));
app.get("/", async (_req, res) => {
var compute = fork("child.js")
compute.send('start');
compute.on("message", result => {
res.send(result)
})
})
它是附帶的child.js
文件:
process.on("message", (msg) => {
var date1 = new Date();
var start_sec = date1.getSeconds();
setTimeout(() => {
var date2 = new Date();
var fin_sec = date2.getSeconds();
process.send("Starting at: " + start_sec + " / Finished at: " + fin_sec);
}, 5000);
});
當我快速依次打開兩個瀏覽器到localhost:3001/
,我希望它們都將在5秒鍾后返回。 例如,如果我在時間= 13時打開一個瀏覽器,而在時間= 14時打開第二個瀏覽器,則我希望瀏覽器分別顯示Starting at 13 / Finished at 18
和Starting at 14 / finished at 19
。 而是顯示Starting at 13 / Finished at 18
和Starting at 18 / Finished at 23
。
為什么第二個請求等待第一個請求完成? 我將如何修改此代碼以獲得預期的結果?
您的代碼很好,我設法在2個firefox選項卡上Starting at: 54 / Finished at: 59
以下位置Starting at: 53 / Finished at: 58
Starting at: 54 / Finished at: 59
。
但是,如果您使用2個chrome瀏覽器執行此操作,則第二個chrome標簽會等待第一個chrome瀏覽器完成。 我不知道確切的解釋,但這就是Chrome處理多選項卡請求的方式。
這是Chrome特有的“功能”。 如果您將兩個相同的請求發送到同一主機,Chrome會將第二個請求排隊,直到第一個請求響應為止。 其他瀏覽器(例如Firefox)則不這樣做。 大概有人認為,通過等待第一個請求完成,他們可以防止不必要的服務器過載。
您可以通過支持多個執行相同操作的路由,然后為第一個和第二個請求使用單獨的路由(例如/1
和/2
。 您可以在路徑上嘗試使用查詢參數,看看如果查詢參數不同(例如/?a=1
和/?a=2
Chrome瀏覽器是否會繞過該功能。
在運行我自己的測試時,查詢參數似乎足以滿足對Chrome瀏覽器的請求,從而避免了排隊並讓它們並行運行。
我確認了這兩個URL的問題:
http://localhost:3001/
http://localhost:3001/
我避免了以下兩個URL的問題:
http://localhost:3001/?a=1
http://localhost:3001/?a=2
這種行為是由express
引起的。 如果在fork之前添加一些console.log
,您將看到請求被阻止,直到將響應發送到客戶端為止。
app.get("/", (req, res) => {
console.log('A');
var compute = fork("child.js")
compute.send('start');
compute.on("message", result => {
res.send(result)
})
})
您將看到一個A,然后響應出現在瀏覽器1中,然后您將獲得針對瀏覽器2的A。
為了實現您的目標,您需要建立websocket連接,或使用服務器推送到客戶端 。
如果您將代碼更改為此
app.get("/", (req, res) => {
var compute = fork("child.js")
compute.send('start');
compute.on("message", result => {
console.log(result)
})
res.status(200).send('OK')
})
您將在控制台中看到自己想要的輸出。
Starting at: 36 / Finished at: 39
Starting at: 38 / Finished at: 41
但是同樣,在快速HTTP中,您無法第二次將響應發送到客戶端。
app.get("/", (req, res) => {
var compute = fork("child.js")
compute.send('start');
compute.on("message", result => {
res.send(result) // Won't work!!!
})
res.status(200).send('OK')
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.