2010-12-15 20 views
1

私はいくつかのクエリ結果を取得するための無名関数を持つこのjsクラスを持っています。結果を扱う関数は匿名であるため、結果をthis.var変数に保存することはできず、これ以降、ウィンドウオブジェクトへの匿名関数参照で他の場所で使用することはできません。関数の戻り値として返すことはできません。その結果を他のどこかで利用できるようにするにはどうすればよいですか?Javascriptの無名関数の質問

someObject = { 
    // this.db is created, no need to paste that code 
    dbGetAnimals: function() { 
     this.db.readTransaction(function(tx) { 
      tx.executeSql("SELECT * FROM animals", function(tx, results){ 
       return results; 
      }) 
     }); 
    }, 
    printAllAnimals: function() { 
     var animals = this.dbGetAnimals(); 
     alert (animals);// undefined 
    } 
} 

someObject.printAllAnimals(); 
+1

dooooontはjavascript呼び出しからsqlを送信するため、多くの攻撃が発生します。 –

+0

ウェブストレージメイト。投稿する前にlol:http://www.html5rocks.com/tutorials/webdatabase/todo/?todo = sddf –

答えて

3

thisの参照を保持するローカル変数を作成することができます。あなたの無名関数はクロージャになるので、そのローカル変数を見ることができます。

dbGetAnimals: function() { 
    var myself = this; 
    this.db.readTransaction(function(tx) { 
     tx.executeSql("SELECT * FROM animals", function(tx, results){ 
      myself.var = results; 
     }) 
    }); 
}, 
+2

これは最も簡単な方法です。しかし、私はそれが醜いと思う。コンテキスト内で実行するためにコールバックが必要な場合は、libを使用してコンテキストをバインドするだけです。 libを使用していない場合は、これが方法です。問題の詳細な説明については、http://www.prototypejs.org/api/function/bindを参照してください。 –

0

executeSqlで無名関数を定義することによってdbGetAnimals戻った後になりますクエリcompmetes、まで実行されていないコールバック関数であるので、これが起こっています。それでdbGetAnimalsへのあなたの呼び出しは未定義に戻っています。

あなたはexecutSqlコールバック内からクエリresutlsを受信するコールバック関数を渡す必要があります:

someObject = { 
    // this.db is created, no need to paste that code 
    dbGetAnimals: function (callback) { 
     this.db.readTransaction(function(tx) { 
      tx.executeSql("SELECT * FROM animals", function(tx, results){ 
       callback(results); 
      }); 
     }); 
    }, 
    printAllAnimals: function() { 
     this.dbGetAnimals(function(animals) { 
      alert(animals) 
     }); 
    } 
} 


someObject.printAllAnimals(); 
+0

私は以下を取得します。未知ReferenceError:動物が定義されていません –

+0

@Tim:Oh duh。そのコードには同じ問題がありました。 'alert()'はクエリが実際に実行される前に実行されます。私は上記のコードを修正しました。 – josh3736

+0

これでも問題は解決しません。 alert()関数はそのコールバック関数の中で動くかもしれませんが、残りのクラスでは "animals"を利用できるようにする方法がありません。 'printAllAnimals'を呼び出すと、オブジェクト自体の内部に 'animals'が返されます。 –

2

あなたは非同期やりたい伝統的な同期/非ブロックのプログラミングを行うにしようとしていますプログラミング。

var someObject = function()({ 
    this.dbGetAnimals = function (callback) { 
     db.readTransaction(function(tx) { 
      tx.executeSql("SELECT * FROM animals", function(tx, results){ 
       callback(results); 
      }) 
     }); 
    }, 

    this.printAllAnimals = function (callback) { 
     this.dbGetAnimals(callback); 
    } 
})(); 

someObject.printAllAnimals(function(animals) { 
    alert(animals); 
} 

はこれを行うには非常にクリーンな方法がありますが、非同期プログラミングのためのあなたの代わりに直接リターンのコールバックに全力を尽くすことを学ぶ必要があります。

+0

なぜこれが大きな問題であるかを私の状況で説明します。私は内部にグリッドを持つ小さなExtJsアプリケーションを構築しています。最初にExtJSウィンドウがあり、そのウィンドウにグリッドを追加します。グリッドではアイテムに何かを表示する必要があります。このタイプのリクエストとコールバックが面倒な場合は、グリッドの値を単純に返すことは不可能です。私はトランザクションを作成しなければならず、トランザクション内でウィンドウとグリッドを構築する必要があります。あなたの例では、 'animals'はまだ 'printAllAnimals'のコールバック関数の中に閉じ込められています。私はhttp://pastebin.com/3a8GQG8Fで完全な例を作りました。 –

+0

これをHTMLページに挿入して、クローム開発ツールを使用してローカルストレージを監視することができます。この例からわかるように、alert(animals)は常に定義されていない戻り値を返します。その結果をコールバック関数の外部で使用するにはどうすればよいですか? –