在javascript类/libs中处理异步事件而不绑定

在javascript类/libs中处理异步事件而不绑定,javascript,class,xmlhttprequest,bind,Javascript,Class,Xmlhttprequest,Bind,这是我的代码 function dl(name){ this.name=name; this.getInfo(); }; dl.prototype={ getInfo:function(){ this.x=new XMLHttpRequest; this.x.open('GET',this.name); this.bind=this.setInfo.bind(this); this.x.addEventListener('load',this.bind,false);

这是我的代码

function dl(name){
 this.name=name;
 this.getInfo();
};
dl.prototype={
 getInfo:function(){
  this.x=new XMLHttpRequest;
  this.x.open('GET',this.name);
  this.bind=this.setInfo.bind(this);
  this.x.addEventListener('load',this.bind,false);
  this.x.send();
 },
 setInfo:function(){
  this.info=this.x.response;
  this.x.removeEventListener('load',this.bind,false);
  delete this.bind;
  delete this.x;
  this.insertDOM();
 }
};
我使用
函数dl(){}
的方法,因为我想用
这个
访问所有东西

我使用
prototype
,因为当我创建许多
新dl(SOMEURL)
时,它不会触及内存

但是是的,因为它里面有很多xhr2函数,所以我需要找到正确返回所有内容的最佳方法

所以通常使用xhr2是非常棒的

function ajax(a,b,c){ //url,function,placeholder
 c=new XMLHttpRequest;c.open('GET',a);c.onload=b;c.send();
}    
//example onload function    
function b(){ //don't even need event....
 console.log(this.response)
}
好:我只传递函数引用(没有参数,没有奇怪的参数,me变量..)

坏:在一个类中,我丢失了指向我的类的
指针

因此,我开始在类中定义xhr对象

this.x=new XMLHttpRequest;
并使用
bind
将其传递给我的下一个函数this.setInfo

但是要在以后删除eventlistener,我需要定义一个包含绑定函数的新变量

this.bind=this.setInfo.bind(this);
我真的很讨厌这一点。(我正试图使用尽可能多的变量和低内存)

我甚至不知道这是否真的消除了这个事件

我正在考虑的另一个解决方案是将它引用到xhr2对象

function dl(name){
 this.name=name;
 this.getInfo(this.name);
};
dl.prototype={
 getInfo:function(){
  var x=new XMLHttpRequest;
  x.that=this;
  x.open('GET',this.name);
  x.addEventListener('load',this.setInfo,false);
  x.send();
 },
 setInfo:function(){
  this.that.info=this.response;
  this.removeEventListener('load',this.setInfo,false);
  this.that.insertDOM();
  delete this.that;
 }
};
A.
这个。那个
只是一个引用,还是它填满了内存

我需要成为舒尔的一员,在完成每项功能后,我都会删除/清除我不再需要的所有变量,以帮助垃圾收集器

B.编写这种类型的javascript类有更好的解决方案吗

ps:是否有更优雅的方法初始化dl中的第一个函数


这门课的目的是什么??

这是chrome的下载管理器

它是如何工作的???

我将下载链接放入
输入
字段

该类将
新dl(SOMEURL)
添加到数组中

使用php cUrl脚本检索文件信息

将文件信息存储在类中

并执行另一个xhr,根据文件的大小检索文件的第一个块

该区块将附加到先前创建的
窗口.webkitrequestfilesystem
文件中

然后,它继续在xhr请求上循环,直到所有块都被下载并附加到文件系统


将文件偏移量状态保存到
窗口。LocalStorage
使我有机会在以后继续下载。

好的,我已经让脚本正常工作了,但我做了一些更改。首先,我使用put x.that并用一个局部变量(instance)替换它,该变量可以在onreadystatechange事件中使用。其次,我添加了一个onreadystatechange事件,允许您在加载ajax请求时运行函数,我还修改了事件侦听器,以便它们能够工作,但我建议使用onreadystatechange。第三,我添加了一些要测试的东西,代码可以在Chrome上运行。最后,我更改了setInfo,以便它将ajax请求的响应作为参数。我想这就是我所做的一切,代码如下:

function dl(name){
    this.name = name;
    this.getInfo(this.name);
};
dl.prototype = {
    getInfo:function(){
        var instance = this;
        var x = new XMLHttpRequest();
        x.open('GET', this.name, false);

        // onreadystatechange event
        x.onreadystatechange = function(){
            if(x.readyState == 4){
                if(x.status == 200){
                    instance.setInfo(x.responseText);
                } else {
                    /*
                        there was a network failure 
                        (File Not Found, Internal Server Error ...)
                    */
                }
            }
        }

        // if you really want to use event the listeners you had previously:
        this.request = x;
        x.addEventListener('load', function(){
            instance.setInfo(x.responseText);
        } ,false);

        x.send();
    },
    setInfo:function(response){
        this.info = response;

        // if you used the event listeners
        this.request.removeEventListener('load', function(){
            instance.setInfo(x.responseText);
        } ,false);
        delete this.request;

        // this.insertDOM();
        // I just added this for testing purposes only
        document.body.innerHTML = this.info;
    }
};

// added for testing
window.addEventListener("DOMContentLoaded", function(){
    var dlTest = new dl("filetoget")
}, false);
希望这有帮助。

以下是新代码:

function dl(name, callback) {
    this.name = name;
    this.callback = callback;
    this.getInfo();
}
dl.prototype = {

 getInfo:function(){
  var x=new XMLHttpRequest;
  x.that=this;
  x.open('GET',this.name,false);
  x.addEventListener('load',this.setInfo,false);
  x.send();
 },
 setInfo:function(){
  this.that.info=this.response;
  this.removeEventListener('load',this.setInfo,false);
  //this.that.insertDOM();  
  // when you need to refer back
     this.that.callback(this.responseText);

  delete this.that;
 }   
}

function call() {
    var a = 1;
    var b = 2;

    new dl("filetoget", function (response) {
        console.log(a + b);
        console.log(response);
    });
}

call();

在这个漫长的问题中有很多错误的假设;因为这个原因,回答这个问题很有挑战性。如果你有答案,那就太酷了。。。你的错误假设是什么意思?我的英语很差。。sryi也找不到合适的标题来解释我的意思。。。关键是创建一个lib(function(){})(),它与其他lib没有问题,并且可以完全访问其中的每个事件和变量。但是一个大问题是函数不返回this pointer,不需要从XHR对象中删除事件侦听器。垃圾收集器将找出如何回收这些垃圾。一般来说,在您真正开始遇到内存问题之前,您不值得花时间猜测垃圾收集器需要什么。。。garbade收藏家怎么了?就像解决方案21一样。”var instance=this'是对它的引用,它包含了大量内容并填满了整个内存。2.‘setInfo:function(response)’我选择‘this’可以访问我需要的每个参数,而无需通过函数传递。3. 'onreadystatechange’我使用‘onload’进行测试,因为它很短,在chrome上运行非常完美。4.执行instance.setInfo 2次。5.你不能用RemoveEventListener删除匿名函数我的两个解决方案都有效。。。但是我需要以正确的方式返回onload/onreadystatechange函数中新创建的dl()对象的引用。我认为绑定函数或传递this.that或实例不是一个好方法。el.addEventListener('readystatechange',f,false)与el.onreadystatechange是一样的。。除了evlist。。您可以添加多个侦听器,还可以使用适当的removeEventListener。哦,在这种情况下,您可以从dl()函数内部使用
参数.callee.caller
,这应该会为您提供调用dl的函数。或者你可以找到一些方法来使用某种回调函数。我认为使用
onreadystaechange=function()
看起来更好,但这基本上是我的第二个解决方案的代码。它可以。。。但是在xhr对象中创建的引用呢。。。它会直接进入垃圾收集器,还是会在某个隐藏的地方继续填充内存?据我所知,更改
this.that.callback(this.responseText)
this.that.callback(this)将发送请求的副本,而不是实际的请求。我来做个快速测试