2012-02-24 22 views
2

C#の背景からくると、私はおそらく完全に間違った視点からJavaScriptを見ているでしょう。JavaScriptで非同期関数の結果を処理する方法

1分の間に非同期の利点を残して、 は、単にHTML5ページのSQLiteデータベースから値を取得したいとします。 私が見てみたいことは

var something = db.getPicture(1); 

のようなものが、今、このの(おそらく非常にナイーブ)の実装を検討している:

this.getPicture(id) 
{ 
    this.database.transaction(function(tx) 
    { 
     tx.executeSql('SELECT ......', null, function(tx, results) 
     { 
      if (results.rows.length == 1) 
       return results.rows.items(0).Url; //This of course does not resturn 
                //anything to the caller of .getPicture(id) 
     } 
    }, 
    function(error) 
    { 
     //do some error handling 
    }, 
    function(tx) 
    { 
     //no error 
    });      
} 

まず第一に、それは、ネストされた関数と第二の一つの大きな混乱です...私がデータベースから得た結果を.getPicture()関数の値として返す方法はありません。

そして、これは簡単なバージョンですが、私は最初のテーブルからインデックスを盗んしたい場合、 はその後、その次のクエリでそのインデックスを使用して、どのような...

はJavaScript開発者のために、この正常です、私は完全に間違っている、解決策などありますか?

+2

はい、完全に間違っています:-)事の非同期性を扱うために、*コールバック*関数を渡します。これらはランタイムシステムによって起動され、コールバックからの戻り値は意味をなさない。 – Pointy

+0

getPictureを返すには、非同期の処理が完了するまでgetPictureの実行をブロックし、非同期コールバックを使用して戻り変数を設定する必要があります。 – Alex

+0

@Pointy:あなたのコメントを回答にア​​ップグレードすることを検討してください –

答えて

2

JavaScript(WebブラウザやNode.jsのような非同期環境)の基本パターンは、 APIが提供する "成功"コールバックで操作が完了する必要があります。あなたの場合、それはあなたの "executeSql()"メソッドに渡される関数になります。その設定において

this.getPicture = function(id, whenFinished) 
{ 
    this.database.transaction(function(tx) 
    { 
     tx.executeSql('SELECT ......', null, function(tx, results) 
     { 
      if (results.rows.length == 1) 
       whenFinished(results.rows.items(0).Url); 
     } 
    }, 

、データベース操作の結果が「getPicture()」が呼び出されたときに提供される関数へのパラメータとして渡されます。

JavaScript関数は、クロージャーを形成するため、呼び出しコンテキストのローカル変数にアクセスできます。つまり、 "whenPinished"パラメータとして "getPicture()"に渡す関数は、 "getPicture()"が呼び出された時点でライブだったローカル変数にアクセスできます。

関連する問題