0

ネットワーク経由で非同期リクエストを実行し、データを「返す」ためのコールバックを取る JavaScript 関数がいくつかあります。これを使用すると、これがどのように見えるかの例を次に示します。

RemoteQuery(server,query,function(ret) {
  // do something with ret
})

問題は、連続して複数のクエリがある場合、コードが非常にネストされて管理が難しくなることです。私はスコープ変数に依存しているので、これらの関数のそれぞれを個別のトップレベル関数に切り出すこともできません。おもちゃの例を次に示します。

RemoteQuery(server,query1,function(ret) {
      var x = ret[5]
      RemoteQuery(server,query2,function(ret) {
          var y = ret[3]
          if (x + y > 10) {
              RemoteQuery(server,query2,function(ret) {
                  // do more stuff
              })
          }      
      })
})

明らかに、クエリが 2 つまたは 3 つ以上あると、見苦しくなり始めます。それ以上のクエリがある可能性もあります。

理想的には、ネストなしで上記を表現したいと思います。

ret = RemoteQuery(server,query1)
var x = ret[5]
ret = RemoteQuery(server,query2)
var y = ret[3]
if (x + y > 10) {
    ret =RemoteQuery(server,query2)
    // do more stuff
}

しかし、私が考えた唯一のことは、javascriptを解析し、コールバックを持つ関数を認識し、正しい形式で書き直して評価することですが、これは非常に複雑に思え、デバッグが非常に難しくなります.

これを行うためのより良いメカニズムはありますか?

4

3 に答える 3

1

それを行う「適切な」方法は、それらの関数宣言を記述し、スコープ変数に依存しないようにすることです(したがって、それらを各関数に渡します)。何かのようなもの:

var myFunc1 = function(x, ret1) { 
  RemoteQuery(server, query, function(ret2) { 
    var y = ret[3];
    myFunc2(x, y, ret2);
  });
};

var myFunc2 = function(x, y, ret) { /* do more stuff */ };

RemoteQuery(server, query, function(ret1) {
  var x = ret[5];
  myFunc1(x, ret1);
});

これらの RemoteQuery(ies) を非同期で呼び出す必要があるため、質問で提案したソリューションを実際に実行する方法はありません。オブジェクトを使用するとDeferredうまくいくかもしれませんが、関数を再構築する必要があると思います(ネストを避けることを目指しているため)。

于 2012-06-30T19:19:11.017 に答える
0

連鎖関数の配列はどうですか?

function R1 (server, query, callback)
{
    RemoteQuery(server, query, function(ret) {
        // process ret
        if (x + y > 10)
          callback();
    }
}

function R2 (server, query, callback)
{    
    RemoteQuery(server, query, function(ret) {
        // process ret
        callback();
    }
}

function R3 (server, query, callback)
{
    RemoteQuery(server, query, function(ret) {
        // process ret
        callback();
    }
}

var functions = [R1, R2, R3]

function callAll(a, server, query)
{
    var callNext = function(callback, i)
    {
        if (i < a.length)
            a[i](server, query, function() { callback(callback, i + 1); });
    }
    callNext(callNext, 0);
}

callAll(functions, 'server', 'query');
于 2012-06-30T19:24:44.723 に答える
0

JQueryDojoの両方でフレームワークを使用したい場合(他の人も使用していると思います!) には、優れた代替手段となる遅延オブジェクトが含まれています。

于 2012-06-30T19:13:34.887 に答える