2015-12-15 115 views
0

我在koa有一個端點,它從數據庫加載很多數據,然後根據它計算一些結果。這可能需要幾秒鐘。koa是否提供取消請求?

如果瀏覽器取消它,請求會發生什麼?就像瀏覽器選項卡被關閉等一樣。

例如,即使瀏覽器取消或koa足夠聰明,只要停止對此請求啓動的任何操作,就可以填充cache.c

const cache = {} 
router.get('/data', function *(next) { 

    if (cache.c) return this.body = cache.c 

    // somewhere here the browser cancels the request 
    //--- 
    const a = yield db.getA() 
    const b = yield db.getB() 
    cache.c = yield calculateC(a,b) 
    //--- 

    this.body = cache.c 

}) 

回答

1

你的生成器函數將得到產生/以其整體評價無論何時請求插座關閉(例如用戶關閉選項卡)的。

僅僅因爲套接字關閉而停止進一步的發生器執行並不是Koa可以做出的假設。

例如,假設Koa是否自動停止發生器執行,並且用戶在yield query('ROLLBACK')有機會清理db連接之前關閉套接字。現在你有一個僵化的數據庫連接卡在池中。也許還有更好的理由。

所以,是的,Koa會一直執行您的生成器函數,直到完成爲止,此時響應將通過您的中間件備份並返回到Koa的控制中,因爲套接字已關閉。

如果你想知道當用戶關閉的標籤,所以你可以實現自己的短路行爲,你可以監聽請求插座上的"close"事件:

const cache = {} 
router.get('/data', function *(next) { 
    if (cache.c) return this.body = cache.c; 

    var closed = false; 
    this.request.socket.on('close', function() { 
    closed = true; 
    }); 

    if (closed) return; 
    const a = yield db.getA(); 
    if (closed) return; 
    const b = yield db.getB(); 
    if (closed) return; 
    cache.c = yield calculateC(a,b); 

    this.body = cache.c; 
}) 
+0

好知道:)我的想法是保存長時間運行計算的結果,以便用戶回來時可以回收它們。 –

+1

在這種情況下,您可能只想考慮後臺處理模式。在路徑中,在作業表中插入未完成的作業。在後臺隊列或cron作業或setInterval循環中,甚至在向用戶返回響應之後,處理作業並將其狀態設置爲「已完成」。當用戶檢查他們的頁面時,可以顯示「仍在處理中」或任務的結果。然後,您不需要讓用戶同步等待計算完成,無論他們是否關閉了選項卡,都可以這樣做。 – danneu