2017-07-08 42 views
-2

我試圖運行一個FOR循環,其中需要在另一個函數中再次運行的變量,我需要將它們編碼出第一個函數 但函數receive他們爲「未定義」。無法在函數內傳遞全局變量

當變量在collectionChecking函數中除了ledTypes2以外的局部變量時,handleResponse2的函數試圖調用它時,hostIndx2的變量未定義。此函數應該將響應呈現爲HTML頁面內ledTypes2方法的圖標。

var fetch = require('node-fetch'); 

var ledTypes = { 
    green: "<img id='logo' src='green.png' height='30' width='30'>", 
    red: "<img id='logo' src='red.png' height='30' width='30'>", 
    yellow: "<img id='logo' src='yellow.png' height='30' width='30'>" 
}; 

var hosts2 = ['http://host1.com','host2.com','host3.com','host4.com']; 
var hostIndx2 = 0; 

var lengthVal = hosts2.length; 
var token = '1213232431'; 
    function collectionChecking() { 

     console.log("im inside the func" + hostIndx2 + "---" + lengthVal); 
     for (; hostIndx2 < lengthVal; hostIndx2++) { 
      console.log(hostIndx2); 
      let url = hosts2[hostIndx2]; 
      // sendReq(); 
      fetch(url , {method: 'GET', headers:{"X-AUTH-TOKEN": token, "Content-Type": "text/plain"}, timeout: 30000} 
      ).then(function (res, hostIndx2) { 
        console.log(res.status, hostIndx2); 
        handleLedResponse2(res, hostIndx2); 

       }); 
     } 
    } 

function handleLedResponse2(res, hostIndx2) { 
    var curSpan = document.getElementById('col_host_' + hostIndx2); 
    console.log("IM HERE" + res.status + "---" + hostIndx2); 
    if (res.status === 200 || res.status === 204) { 
     curSpan.innerHTML = ledTypes.green; 
    } else if (res.status === 500 || res.status === 404) { 
     curSpan.innerHTML = ledTypes.red; 
    } else if (res.status === 300 || res.status === 301 || res.status === 302) { 
     curSpan.innerHTML = ledTypes.yellow; 
    } 
} 
+0

請更具體地說明您遇到的問題。哪些確切的變量是未定義的,哪些代碼行?而且,「需要將它們編碼出第一個函數」是什麼意思?請更確切地說明您的問題以及您想要達到的目標。 – jfriend00

+0

謝謝,當handleResponse2的函數試圖調用他時,hostIndx2的變量是未定義的。此函數應該將響應呈現爲HTML頁面內ledTypes2方法的圖標。 –

回答

0

這段代碼有很多錯誤。

對於初學者,您不能在異步響應中使用for循環索引變量。在調用handleLedResponse2()之前,for循環將完全結束,因此它將不具有所需的值。

其次,你聲明.then()處理有在這條線的兩個參數:

.then(function (res, hostIndx2) { 

通過規範.then()處理程序只傳遞一個參數。因此,您正在定義一個名爲hostIndx2的參數,該參數始終爲undefined,它將「隱藏」相同名稱的較高範圍變量,因此您無法訪問它。
這就是爲什麼你看到的值始終是undefined。解決的第一件事是改變上面的代碼,只是這樣的:

.then(function (res) { 

這將使你獲得更高的作用域hostIndx2變量(這將不再是undefine)。但是,由於混合了同步for循環和異步fetch()調用,因爲在任何fetch().then()處理程序被調用之前,for循環將運行完成,所以它可能不會具有期望的值。

我認爲這解釋了代碼的這一部分有什麼問題,但我不能完全推薦完整的修補程序,因爲我不確定您要做什麼。我會理論上認爲hostIndx2不應該是一個更高範圍的變量,因爲這隻會導致問題,併爲其他事物帶來麻煩。它應該是一個局部變量,然後你應該把它作爲參數傳遞給你想要訪問它的任何東西。

要修復異步訪問問題,有多個選項。您可以切換到在for循環中使用let來定義它,並且每次調用循環都將獲得它自己的單獨版本的變量(解決異步訪問問題)。或者,您可以更改循環以使用forEach,這將爲每個循環調用創建一個新的唯一作用域。


隨着對你要怎樣做一些猜測,這裏的清理版本:

const fetch = require('node-fetch'); 

const ledTypes = { 
    green: "<img id='logo' src='green.png' height='30' width='30'>", 
    red: "<img id='logo' src='red.png' height='30' width='30'>", 
    yellow: "<img id='logo' src='yellow.png' height='30' width='30'>" 
}; 

const hosts2 = ['http://host1.com','http://host2.com','http://host3.com','http://host4.com']; 
const token = '1213232431'; 

function collectionChecking() { 
    hosts2.forEach(function(url, index) { 
     console.log("im inside the func" + index); 
     fetch(url , {method: 'GET', headers:{"X-AUTH-TOKEN": token, "Content-Type": "text/plain"}, timeout: 30000}).then(function (res) { 
      console.log(res.status, index); 
      handleLedResponse2(res, index); 
     }); 
    } 
} 

function handleLedResponse2(res, hostIndx2) { 
    let curSpan = document.getElementById('col_host_' + hostIndx2); 
    console.log("IM HERE" + res.status + "---" + hostIndx2); 
    if (res.status === 200 || res.status === 204) { 
     curSpan.innerHTML = ledTypes.green; 
    } else if (res.status === 500 || res.status === 404) { 
     curSpan.innerHTML = ledTypes.red; 
    } else if (res.status === 300 || res.status === 301 || res.status === 302) { 
     curSpan.innerHTML = ledTypes.yellow; 
    } 
} 

附:我在這裏有點困惑,因爲你的問題被標記爲node.js,看起來你正在使用node-fetch(這意味着一個node.js環境),但是你顯示的是document.getElementById(),這不是你可以在節點中使用的東西。js - 通常是可以在瀏覽器中運行的代碼。

+0

謝謝,我會嘗試你的解決方案,讓你知道結果。這是我第一次處理這個用例,並且在路上遇到很多問題。這段代碼的理由是向多個主機發送GET請求,並在HTML頁面(這是一種儀表板)中的saperated span標記中呈現它們的響應。但是這是一個跨域請求,所以我使用的是獲取函數而不是XMLhttp處理程序。 –