Ajax基石脚本异步并发调用参数传递

日期: 2008-04-14 来源:TechTarget中国

  在Ajax开发框架中,最基本的划分是服务器端和客户端。服务器端相对来说比较简单,只要是可以开发动态网页的语言都可以胜任;客户端浏览器就是JScript/JavaScript的天下了,好像没有看到有VBScript做的Ajax客户端库,就算它只支持IE。由于客户端依赖于脚本并运行在浏览器中,似乎比服务器端的可实现和可管理性还要差些。


  这里我说一下Ajax中的A, Asynchronous调用的一些问题。如果我们在异步调用时不为方法传递任何的参数,那么这个问题也就简单甚至不存在了。但是事实上,我们开发一些稍微复杂些的功能时,对于”脚本异步并发调用参数传递”这个功能是很需要的。说的严重些,可以把这个功能看成Ajax客户端框架能否真正Asynchronous的基石。对于异步调用参数传递的问题,可以看我以前的一篇文章”使用匿名函数为setInterval传递参数”。虽然文中的示例很好地解决了参数传递问题,但是我们看看下面的示例,看会发现什么呢?


  function foo()
  {


  var param = 100;


  window.setTimeout(function()


  {


  intervalRun(param);


  }, 0);


  param = 0;


  }


  function intervalRun(times)


  {


  alert(times);


  }
 
  我们执行foo,会得到什么样的alert结果呢?100? or 0?,答案是:0。其实写过内嵌函数就知道,这里要真确的传入100,需要这样改写foo方法:


  function foo()
  {


  var param = 100;


  var __param = param;


  window.setTimeout(function()


  {


  intervalRun(__param);


  }, 0);


  param = 0;
 
  // 这样添加一个变量来存储param就可以了,这下执行foo得到的alert结果就是:100。


  上面这个修正本身没有问题,可是如果我在并发执行的情况下,就可能又有新的问题。示例代码:


  function doTick()
  {


  var tick = new Date().getTime();


  var __tick = tick;


  var foo = function()


  {


  GetTick(__tick);


  };


  window.setTimeout(foo, 3000);


  }


  function GetTick(tick)


  {


  // to do something depend on tick parameter


  }
 
  当我们在调用doTick方法时,如果以小于3000ms的频率并发,将会导致前一次的tick变量被后面执行的执行过程修改的问题,从而导致GetTick方法取到错误的tick参数。也就是说必须把doTick方法看成一个,需要”本身执行时间+3000ms”才能运行完的方法,然后再保证并行的执行doTick方法才不会出错。这样的限制条件显然是不可接受的,那么我们该怎么办呢?


  其实我们只需要使用内嵌函数自身帮助我们传递参数就行了,修改后的示例如下:


  function doTick()
  {


  var tick = new Date().getTime();


  var foo = function()


  {


  var __tick = foo.params[0];


  GetTick(__tick);


  };


  foo.params = [tick];


  window.setTimeout(foo, 0);


  }
 
  由于内嵌函数构造出一个Closure Scope,它将帮组我们保存参数的Context,使我们获得真正的”异步并发调用参数传递”效果。


  使用匿名函数为setInterval传递参数


  在使用JScript的时候,我们有时需要间隔的执行一个方法,比如用来产生网页UI动画特效啥的。这是我们常常会使用方法setInterval或setTimeout,但是由于这两个方法是由脚本宿主模拟出来的Timer线程,在通过其调用我们的方法是不能为其传递参数。


  我们常用的使用场景是:


  window.setTimeout(“delayRun()”, n);
  window.setInterval(“intervalRun()”, n);


  window.setTimeout(delayRun, n);


  window.setInterval(intervalRun, n);
 
  显然强行代参数的调用:


  window.setTimeout(“delayRun(param)”, n);
  window.setInterval(“intervalRun(param)”, n);


  window.setTimeout(delayRun(param), n);


  window.setInterval(intervalRun(param), n);
 
  都是错误的,因为string literals形式的方法调用,param必须是全局变量(即window对象上的变量)才行;而function pointer形式的调用,完全错误了,这是把函数的返回值当成了setTimeout/setInterval函数的参数了,完全不是我们所望的事情。


  解决这个问题的办法可以使用匿名函数包装的方式,在以下scenario中我们这么做:


  function foo()
  {


  var param = 100;


  window.setInterval(function()


  {


  intervalRun(param);


  }, 888);


  }


  function interalRun(times)


  {


  // todo: depend on times parameter


  }
 
  这样一来,就可以不再依赖于全局变量向delayRun/intervalRun函数中传递参数,毕竟当页面中的全局变量多了以后,会给脚本的开发、调试和管理等带来极大的puzzle。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • Oracle借助RESTFUL API扩展移动端版图

    Oracle公司推出新版本的云移动应用后端总线,以及与之配套的开发框架,可让开发者通过Eclipse或者Oracle JDeveloper IDEs或者HTML5来创建移动应用。

  • iCloud开发框架:未来将让所有人受益

    在今年WWDC大会上,苹果发布了新的“限时免费”开发框架CloudKit,它能够让应用软件开发商接入苹果iCloud云服务,让他们更为轻松地将云服务整合到移动应用软件中。

  • 关于微软开源WinJS:开发者必须知道的5件事

    微软宣布将其现有的JavaScript框架WinJS开源,转身拥抱Web及移动应用开发者。本文列举出开发者需要密切注意的5件事,详细解读WinJS的前景及优势所在。

  • 八个超实用的jQuery技巧攻略

    jQuery是JavaScript最好的库之一,主要用于制作动画、事件处理,支持Ajax及HTML脚本客户端。文中分享了8个超实用的jQuery代码技巧攻略,希望你会喜欢。