2017-02-27 77 views
0

我在node.js/express應用程序中設置了一個事件發射器。它發出的事件,被前端聽衆抓住。事情是,雖然我可以看到發射被調用一次,但發射器發出相同的事件高達4次。另外,雖然一般情況下,聽衆收到事件並採取行動,但有時沒有任何反應。有沒有人知道我做錯了什麼?SSE發射器多次觸發,有時瀏覽器沒有得到事件

後端:

app.get('/getStatus', isLoggedIn, function(req, res){ 
res.writeHead(200, {'Content-Type': 'text/event-stream'}); 
progressEmitter.on('status',function(newState, job_id, fTime, jobLink){ 
    console.log('Updated state to : ' + newState + ' for job ' + job_id); 
    res.write("event: state\n"); 
    res.write(`data:${newState},${job_id},${fTime},${jobLink}\n\n`); 
    console.log(`Emitted state change data! :${newState},${job_id},${fTime},${jobLink}\n\n`); 
}); 

});

前端:

$(document).ready(function() { 
var state = []; 
var source = new EventSource('getStatus'); 
source.addEventListener('state', function(e) { 
    state = e.data.split(','); 
    for (var ajob in jobsReceived){ 
     if (jobsReceived[ajob].id == state[1]) { 
      jobsReceived[ajob].status = state[0]; 
      jobsReceived[ajob].finished_time = state[2]; 
      console.log(state[0]); 
      if (state[0] === 'saved') jobsReceived[ajob].link = state[3]; 
      break; 
     } 
    } 
    $('#table').bootstrapTable('updateByUniqueId', { 
      id: state[1], 
      row: { 
       status: format_status(state[0]), 
       finished_time: state[2], 
       link: state[0] === 'saved'? state[3]:'' 
      } 
     }); 

}); 

回答

0

在其他問題上花費的時間後,我決定用清醒的頭腦重新審視它,並最終得到了解決。我在這裏發佈,以防有​​人遇到同樣的問題。

這裏發生的是,每次調用progressEmitter.on()時都會添加一個偵聽器。當事件發出時,所有監聽器都會運行。

爲了解決這個問題,當請求關閉時,監聽器必須被移除。這通過調用emitter.removeListener()來完成。由於此函數所需的參數是事件名稱和偵聽器函數,因此更容易命名偵聽器函數。因此,後端代碼更改如下:

app.get('/getStatus', isLoggedIn, function(req, res){ 
    res.writeHead(200, {'Content-Type': 'text/event-stream'}); 
    function statusEvent(newState, job_id, fTime, jobLink){ 
    console.log('Updated state to : ' + newState + ' for job ' + job_id); 
    res.write("event: state\n"); 
    res.write(`data:${newState},${job_id},${fTime},${jobLink}\n\n`); 
    console.log(`Emitted state change data!'); 
} 

    progressEmitter.on('status',statusEvent); 
    req.on('close', function(){ 
    progressEmitter.removeListener('event', statusEvent); 
    }) 
})