Javascript 向XMLHttpRequest添加onerror函数

Javascript 向XMLHttpRequest添加onerror函数,javascript,Javascript,下面是一段代码,使用JavaScript中的HTTP请求预加载文件并将其保存到浏览器缓存中。问题是,如果没有您的帮助,我无法找到跟踪Prelome函数中错误的解决方案: 我知道我们可以将onerror添加到PreloOne中,并且效果很好: xhr.onerror = function() { console.log('onerror happend'); }; 但我想知道我们如何在像oncomplete、onfetched和onprogress这样的prelome函数中做到这一点。大

下面是一段代码,使用JavaScript中的HTTP请求预加载文件并将其保存到浏览器缓存中。问题是,如果没有您的帮助,我无法找到跟踪Prelome函数中错误的解决方案:

我知道我们可以将onerror添加到PreloOne中,并且效果很好:

xhr.onerror = function() {
    console.log('onerror happend');
};
但我想知道我们如何在像oncomplete、onfetched和onprogress这样的prelome函数中做到这一点。大概是这样的:

preload.onerror = items => {
   console.log('onerror happend'); // onerror here
}
function preloadOne(url, done, error) {
  const xhr = new XML HttpRequest();
  // ...
  if(typeof error === 'function') xhr.onerror = error;
  // ...
}
  function preloadOne(url, done) {
    const xhr = new XMLHttpRequest();
    // ...
    xhr.send();
    return xhr;
  }
非常感谢您的任何评论或修改

以下是我目前的代码:

全球工厂{ 导出类型=='object'&&typeof module!=='undefined'?module.exports=工厂: typeof define==='function'&&define.amd?definefactory: 全局。预加载=工厂; }这个,功能{ "严格使用",; 函数prelooneurl,完成{ const xhr=新的XMLHttpRequest; xhr.open'GET',url,true; xhr.responseType='blob'; xhr.onprogress=事件=>{ if!event.lengthComputeable返回false 让item=this.getItemByUrlevent.target.responseURL; item.completion=parseIntevent.loaded/event.total*100; item.download=event.loaded; item.total=event.total; 此.updateProgressBaritem; }; xhr.onload=事件=>{ let type=event.target.response.type; 让blob=newblob[event.target.response]{ 类型:类型 }; 让url=url.createObjectURLblob; 让responseURL=event.target.responseURL; 让item=this.getItemByUrlresponseURL; item.blobUrl=url; item.fileName=responseURL.substringresponseURL.lastIndexOf'/'+1; item.type=类型; item.size=blob.size; doneitem; }; xhr.send; } 函数updateProgressBaritem{ var-sumpletion=0; var maxCompletion=this.status.length*100; 对于此.status的var itemStatus{ 如果itemStatus.completion{ sumpletion+=itemStatus.completion; } } var totalCompletion=parseIntsumCompletion/maxCompletion*100; 如果!不是全部完成吗{ 这是一个进步{ 进度:全部完成, 项目:项目 }; } } 函数getItemByUrlrawUrl{ 对于此状态的var项{ 如果item.url==rawUrl返回项 } } 函数获取列表{ 返回新的PromiseSolve,拒绝=>{ this.loaded=list.length; 对于列表中的项目{ this.onerroritem;//此处为onerror 这个。状态。推{ url:项目 }; this.preload项目,项目=>{ 这个.onfetcheditem; 这是一个; 如果this.loaded==0{ this.oncompletethis.status; 解决这个问题; } }; } }; } 功能预加载{ 返回{ 状态:[], 加载:false, onprogress:=>{}, oncomplete:=>{}, onfetched:=>{}, onerror:=>{},//onerror在这里 取来 updateProgressBar, 第一,, getItemByUrl } } 返回预载; }; //在此预加载 我; 函数预加载{ 恒载预载=预载; 预加载.fetch[ 'https://round-arm-authority.000webhostapp.com/Ultimate%20Video%20Hack/videos/vid1.mp4' ].thenitems=>{ //使用承诺或“完成” console.logitems; }; preload.oncomplete=项目=>{ console.logitems; } preload.onerror=项目=>{ console.log'onerror happend';//这里是onerror } preload.onprogress=事件=>{ console.logevent.progress+'%'; } preload.onfetched=项目=>{ console.logitem; } };
有两种选择。您可以将错误回调作为参数添加,这与使用done回调时所做的一样

如果要使错误回调成为可选的,可以执行以下操作:

preload.onerror = items => {
   console.log('onerror happend'); // onerror here
}
function preloadOne(url, done, error) {
  const xhr = new XML HttpRequest();
  // ...
  if(typeof error === 'function') xhr.onerror = error;
  // ...
}
  function preloadOne(url, done) {
    const xhr = new XMLHttpRequest();
    // ...
    xhr.send();
    return xhr;
  }
在某些方面,这可能更可取,因为您可以在调用xhr.send之前注册错误处理程序。虽然我不知道这是否重要,但我不确定事件循环在这方面是如何工作的

另一种方法是在PreloOne函数末尾返回xhr,如下所示:

preload.onerror = items => {
   console.log('onerror happend'); // onerror here
}
function preloadOne(url, done, error) {
  const xhr = new XML HttpRequest();
  // ...
  if(typeof error === 'function') xhr.onerror = error;
  // ...
}
  function preloadOne(url, done) {
    const xhr = new XMLHttpRequest();
    // ...
    xhr.send();
    return xhr;
  }
然后,您可以轻松地添加自己的事件处理程序:

var preload = preloadOne('https://my.site.com/path', x=> {
  console.log('done');
});
preload.onerror = function(event) {
  console.log('error');
};
编辑:返回xhr解决方案的事件循环注意事项。 在做了一些研究之后,我相信如果在xhr.send之后添加事件侦听器,可能会丢失错误事件。这是基于页面,特别是添加消息部分,其中指出:

在web浏览器中,每当事件发生并且有一个事件侦听器连接到事件侦听器时,都会添加消息。如果没有侦听器,则事件将丢失

因此,尽管直到JavaScript堆栈为空时消息才会得到处理,但XHR错误的消息排队几乎随时都可能发生。或尝试排队,如果处理程序尚未连接

但是,如果您真的想返回xhr并确保事件处理程序有机会被附加,我相信有一种方法可以做到这一点,即更改PreLoadOn e将xhr.send放在setTimeout内


这将把发送抛出事件队列,这意味着它必须等待JavaScript调用堆栈清空,然后等待事件循环的下一个周期。当调用堆栈清空时,应该附加任何错误事件处理程序。

@mplungjan感谢您的编辑。.可能会添加一个返回xhr;在第一节结束时?然后您可以将返回值赋给一个变量,并添加一个onerror处理程序。@David784请您提供一个答案。。。