2017-07-08 25 views
-2

私は別の関数で再実行する必要がある変数を持つFORループを実行しようとしていますが、最初の関数からそれらをコーディングする必要があります しかし、それらは「未定義」です。関数内にグローバル変数を渡すことができません

変数がledTypes2以外のcollectionChecking関数内でローカルである場合、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を使用することはできません。ループforは、handleLedResponse2()が呼び出される前に完全に終了しているため、目的の値はありません。

第二に、あなたは、このライン上の2つの引数を持つように.then()ハンドラを宣言している:.then()ハンドラは引数を1つしか渡された仕様で

.then(function (res, hostIndx2) { 

。したがって、常にundefinedになるhostIndx2という名前の引数を定義しており、同じ名前の上位スコープの変数をアクセスすることができないように「隠す」ことになります。
そのため、値が常にundefinedであることがわかります。修正するために最初にすることは、まさにこのために上記のコードを変更することです:

.then(function (res) { 

あなたが高いにアクセスできるようにすること(それはもはやundefineになることはありません)hostIndx2変数をスコープ。しかし、おそらくfetch().then()ハンドラが呼び出される前にループが完了して実行されるため、同期forループと非同期fetch()コールが混在するため、望ましい値を持たないでしょう。

私はコードのこの部分で何が問題なのかを説明していると思いますが、あなたが何をしようとしているのか分かりませんので完全な修正はお勧めできません。私は、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; 
    } 
} 

P.S.:あなたがやろうとしているものについては、いくつかの推測を使用


は、ここでのクリーンアップバージョンですあなたの質問がnode.jsというタグがついていて、node-fetch(node.js環境を意味する)を使っているように見えますが、ノード内で使用できるものではないdocument.getElementById()が表示されるので、ここで少し混乱します。 。js - 通常はブラウザで実行されるコードです。

+0

ありがとうございます、私はあなたのソリューションを試し、その結果をお知らせします。このユースケースで処理しているのは初めてのことですが、途中で多くの問題があります。このコードの合理的な理由は、GET要求を複数のホストに送信し、応答をHTMLページの一種のダッシュボードにあるスパンタグでレンダリングすることです。しかし、これはクロスドメイン要求なので、XMLhttpハンドラの代わりにfetch関数を使用しています。 –

関連する問題