2017-08-17 44 views
0

我需要處理從websocket連接接收到的數據。在數據模型中,我必須運行2個定時器來計算連接時間。下面是我實現的例子:我無法在vuejs中運行setInterval

var socket = io.connect('http://localhost:3000'); 

window.onload = function() { 

    var vm = new Vue({ 
     el: '#indication', 
     data: { 
      incomingData: [] 
     }, 
     methods: { 
      updateB: function (i, num) { 
       this.incomingData[i].b_number += " (" + num + ")"; 
      }, 
      updateWaitTime: function (i) { 
       ++this.incomingData[i].wait_time; 
      }, 
      updateTalkTime: function (i) { 
       ++this.incomingData[i].talk_time; 
      } 
     } 
    }); 

    socket.on("message", function (msg) { 
     message = JSON.parse(msg); 
     console.log(message) 
     if (message.status === "NewChannel") { 
      var now = new Date() 
      var pos = vm.incomingData.push({ 
       id: message.id, count_of_day: ++counter, 
       a_number: message.callernum, b_number: message.number, date: now.toLocaleString(), talk_time: 0, wait_time: 0 
      }); 
      for (var i = 0; i < vm.incomingData.length; i++) { 
       if (vm.incomingData[i].id === message.id) { 
        console.log("start NCTimer for " + message.id); 
        timersNC[message.id] = setInterval(function() { 
         vm.updateWaitTime(i); 
        }, 1000); 
        break; 
       } 
      } 
      return false; 
     } else if (message.status === "bridge") { 
      for (var i = 0; i < vm.incomingData.length; i++) { 
       if (vm.incomingData[i].id === message.id) { 
        console.log("bridge for " + message.id); 
        vm.updateB(i, message.operator_ext); 
        console.log("STOPPING TALT_TIME HERE"); 
        clearInterval(timersNC[message.id]); 
        delete timersNC[message.id]; 
        break; 
       } 
      } 
      return false; 
     } 

     else if (message.status === "hangup") { 
      for (var i = 0; i < vm.incomingData.length; i++) { 
       if (vm.incomingData[i].id === message.id) { 
        for (var id in timersNC){ 
         if (id === message.id){ 
          clearInterval(timersNC[message.id]); 
          delete timersNC[message.id]; 
          console.log("DELETED NC FROM HANGUP!!!!") 
          break; 
         } 
        } 
        for (var id in timersBR){ 
         if (id === message.id){ 
          clearInterval(timersBR[message.id]); 
          delete timersBR[message.id]; 
          console.log("DELETED BR FROM HANGUP!!!!") 
          break; 
         } 
        } 
        console.log("hangup for " + message.id); 
        vm.incomingData.splice(i, 1); 
        break; 
       } 
      } 
      return false; 
     } 
     else return; 
    }) 
}; 

的數據如下表更新時間:

<div id="indication"> 
     <table class="rtable"> 
      <thead> 
       <tr> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
       </tr> 
      </thead> 

      <tbody id="dynamic_row"> 
       <tr v-for="d in incomingData" :key='d.id'> 
        <td>{{d.b_number}}</td> 
        <td>{{d.queue_number}}</td> 
        <td>{{d.count_of_day}}</td> 
        <td>{{d.date}}</td> 
        <td>{{d.a_number}}</td> 
        <td>{{d.mobile_operator}}</td> 
        <td>{{d.status}}</td> 
        <td>{{d.category}}</td> 
        <td>{{d.wait_time}}</td> 
        <td>{{d.talk_time}}</td> 
       </tr> 
      </tbody> 
     </table> 
    </div> 

該電路的工作原理,直到某一點時出現以下錯誤:

index.js:62 Uncaught TypeError: Cannot read property 'wait_time' of undefined 
    at Vue$3.updateWaitTime (index.js:62) 
    at Vue$3.boundFn [as updateWaitTime] ([email protected]:188) 
    at index.js:83 

我不明白爲什麼會發生這種情況,以及如何使它工作。我提前道歉,如果錯誤是愚蠢的,我是vuejs的絕對初學者。 據我所知,這個問題是在異步刪除和添加元素,但我不知道如何解決它

回答

0

這是因爲for循環已經由setInterval()回調運行的時間已經結束。這意味着i已經增加到與vm.incomingData.length相同的值,但運行時間爲vm.updateWaitTime(i),然後i指向陣列中不存在的項目。

你需要做的是將i範圍作爲每次迭代。如果你能使用ES6語法,你可以寫你的for循環這樣做:

for (let i = 0; i < vm.incomingData.length; i++) { 

即使用let而不是var。如果ES6不是選項,則必須在每次迭代中創建一個新的函數作用域,以創建i的作用域副本。這可通過寫這樣您setInterval()表達來完成:

timersNC[message.id] = setInterval((function (idx) { 
        return function() { 
         vm.updateWaitTime(idx); 
        }; 
       }(i)), 1000); 

...或者:

timersNC[message.id] = setInterval((function (idx) { 
        vm.updateWaitTime(idx); 
       }).bind(null, i), 1000); 
+0

感謝您的解釋,現在我明白是什麼錯誤,但對不幸的是沒有一個建議的方法可以解決我的問題 –