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,识别具有回调的函数,以正确的形式重新编写它们,然后进行eval,但这似乎非常复杂,并且会使调试变得非常困难。

有没有更好的机制来做到这一点?

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

如果您愿意同时使用JQueryDojo框架(我相信其他人也有它!)包含一个延迟对象,这将是一个不错的选择。

于 2012-06-30T19:13:34.887 回答
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 回答