【 以下文字转载自 Google 讨论区 】
发信人: modico (modico), 信区: Google
标 题: gmail client code review,part 12
发信站: 水木社区 (Mon Oct 23 10:12:41 2006), 站内
google如何处理xmlhttp的异步回调?回调函数经常会遇到closure,也因此经常会由于没有小心处理而引起内存泄漏。google的做法是,建立一个登记簿(数组),每个已经开始但尚未结束的xmlhttp都在这个全局数组里引用,给回调函数的参数不是xmlhttp对象引用,而是一个登记簿的索引值,回调函数自己再去登记簿取回实际的xmlhttp对象,用完后,撤销登记。
var pendingXmlHttpArray/*Zm*/ = [];
function registerXmlhttpCallback/*Um*/(xmlhttp, callback)
{
if (g_uaNotIE_KHtml_2/*Es*/) {
xmlhttp.h = callback;
}
else {
var c = pendingXmlHttpArray/*Zm*/.length;
pendingXmlHttpArray/*Zm*/[c] = xmlhttp;
xmlhttp.onreadystatechange = internalXmlhttpCallback/*pZ*/(callback, c);
}
}
function internalXmlhttpCallback/*pZ*/(callback, index)
{
return function()
{
var xmlhttp = pendingXmlHttpArray/*Zm*/[index];
try {
callback(xmlhttp);
}
catch (d) {
dumpException/*Gz*/(d);
}
if (xmlhttp.readyState == 4) {
_setTimeout/*u*/(window, function()
{
xmlhttp.onreadystatechange = doNothing/*Ds*/;
delete pendingXmlHttpArray/*Zm*/[index];
}
, 0);
}
}
}
需要注意的是,这里的回调函数的处理跟_setTimeout函数类似,也包裹了一个内部函数。调用方提供的回调函数接收的参数是一个xmlhttp对象,内部函数的作用是根据索引得到xmlhttp对象,以及做一些其它清理的事情,这样调用方的回调函数可以集中精力处理自己的事情。还有一点,回调的时机,可能会回调多次,因为google不知基于什么理由并不是在readystate的最后完成阶段才去调用回调函数。
--
FROM 218.249.84.*