2012-03-08 10 views
0

私はちょうどjavascriptでカスタムオブジェクトを作成することから始めました。私はthis.someObjVarを以下のコードを使って設定したいが、私のアプローチでは何か間違っている。たぶん、非同期応答はそれ自身のスコープまたはスレッドを使用します。非同期コールバックからオブジェクト変数を設定する方法

// The code below used like: 
someClass = new extfoo.SomeClass(); 
someClass.loadArrFromFile(); 
// this will be called far later after async returns 
someClass.showSomeObjVar(); 

extfoo.js 
========= 
var extfoo = {}; 

extfoo.SomeClass = function() { 
    this.someObjVar = []; 
    this.showSomeObjVar = extfoo.showSomeObjVar; 
    this.loadArrFromFile = extfoo.loadArrFromFile; 
}; 
// Bad results here 
extfoo.showSomeObjVar = function() { 
    // results '0' 
    console.log('showSomeObjVar: ' + this.someObjVar.length); 
}; 

// Async array population 
extfoo.loadArrFromFile = function() { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4) { 
     this.someObjVar = xhr.responseText.split('\r\n') 
     // results '23' elements 
     console.log("someObjVar length: "+this.someObjVar.length); 
    } 
    } 
    // request code ... 
}; 
+0

は '' SomeClass.prototype'のloadArrFromFile'メンバーですか?一番上のコードはそれがそうであることを示唆していますが、私が見るのは 'extfoo.loadArrFromFile'だけです。またthis' 'の値は' xhr.onreadystatechange'コールバック内で変更されますので、 'this.someObjVar = xhr.resp ...' 'あなたはloadArrFromFile内で直接持っていることは同じ参照されないことに注意してください'関数。 –

答えて

0

あなたはthis.someObjVarextfooを参照していることが確実な? extfoo.loadArrFromFile機能でthisオブジェクトがextfooオブジェクト関数自体(xhr.onreadystatechange)を参照し、されていない可能性があります

extfoo.loadArrFromFile = function() { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4) { 

     //I'm going to create a new variable for this function called this.someObjVar 
     //Cause I don't know about extfoo's. 
     this.someObjVar = xhr.responseText.split('\r\n') 
     // results '23' elements 
     console.log("someObjVar length: "+this.someObjVar.length); 

     //Whup, end of the line, I guess I'll just forget about that variable I just made. 
    } 
    } 
    // request code ... 
}; 

があり、この問題を解決する方法はいくつかありますが、テストするためには、してみてくださいextfoo.loadArrFromFilethis機能をextfooに変更してください。ここで

はそれを修正する方法は次のとおりです。

extfoo.loadArrFromFile = function() { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4) { 

     //OOOH you mean that object 
     extfoo.someObjVar = xhr.responseText.split('\r\n') 
     // results '23' elements 
     console.log("someObjVar length: "+extfoo.someObjVar.length); 

    } 
    } 
    // request code ... 
}; 

最後に一つ... extfoo.SomeClass.someObjVarextfoo.someObjVar異なることになっていますか?この場合、このコードは機能しますが、それ以外の場合は、各参照の間にSomeClassを含めることをお勧めします。

+0

あなたは正しいですが、現在のsomeClassインスタンスへの参照を渡す方法はありますか? – User

+0

解答を –

0

これは非同期要求であるため、someClass.loadArrFromFile()は要求が完了するまで待機しないため、完了する前にsomeClass.showSomeObjVar()が呼び出されます。あなたはこのような何かができ

extfoo.loadArrFromFile = function(done) { 
    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4) { 
     this.someObjVar = xhr.responseText.split('\r\n') 
     // results '23' elements 
     console.log("someObjVar length: "+this.someObjVar.length); 
     done(); 
    } 
    } 

あなたは結果を処理するために、終了ハンドラを追加することができます

someClass.loadArrFromFile(function() { 
    someClass.showSomeObjVar(); 
}); 
+0

で更新しました。ただし、 'showSomeObjVar()'を参照すると 'async returns after async returns 'と表示されることを除けば、非同期問題はカバーされた。 –

+0

は申し訳ありませんが、私はあなたの要求がindead非同期の場合はJavaScriptをマルチスレッド化されていないため、要求が完了する前に、その後、loadArrFromFileが返されます最初の投稿 – User

+0

後分後にそのコメントを追加しました。あなたがxhr.sendを行うときに()は、サーバからの応答を待つことはありませんが、次のコードを実行していきます。 onreadystatechange関数は後で(同じスレッドによって)呼び出されます。 –

関連する問題