在没有绑定的情况下处理javascript类/libs中的异步事件

Handling async events in javascript classes / libs without bind

本文关键字:libs 事件 异步 处理 绑定 情况下 javascript      更新时间:2023-09-26

所以这是我的代码

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();
 }
};

我使用function dl(){}方法是因为我想使用this访问所有内容。

我使用prototype是因为当我创建许多new 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)
}

好:我只传递函数引用(没有参数,没有奇怪的那个,我变量…)

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

所以我开始在类中定义xhr对象

this.x=new XMLHttpRequest;

并使用bind将其传递给我的下一个函数this.setInfo

但是为了稍后删除eventlistener,我需要定义一个包含绑定函数的新变量。

this.bind=this.setInfo.bind(this);

我真的很讨厌。(我正在尝试使用尽可能多的变量,并使用低内存)

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

我正在考虑的另一个解决方案是将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;
 }
};

Athis.that只是一个参考,还是充满了内存

我需要注意的是,在每个函数之后,我都会删除/清除不再需要的每个var来帮助垃圾收集器。

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

ps.:有没有一种更优雅的方法来初始化dl中的第一个函数?


这门课是干什么的

它是chrome 的下载管理器

它是如何工作的

我在input字段中放入了一个下载链接

该类将new dl(SOMEURL)添加到阵列

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

将文件信息存储在类中

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

块将被附加到先前创建的CCD_ 10文件。

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

将文件偏移量状态保存到window.LocalStorage中,使我有机会稍后继续下载。

好的,我已经准备好了脚本,但我做了一些更改。首先,我取了put x.that,并将其替换为一个可以在onreadystatechange事件中使用的局部变量(实例)。其次,我添加了一个onreadystatechange事件,允许您在加载ajax请求时运行一个函数,我还修改了事件侦听器,使其能够工作,但我建议使用onreadystate change。第三,我添加了一些要测试的东西,代码可以在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();