Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 仅当xhr.onloadend之前已激发时才解析承诺_Javascript - Fatal编程技术网

Javascript 仅当xhr.onloadend之前已激发时才解析承诺

Javascript 仅当xhr.onloadend之前已激发时才解析承诺,javascript,Javascript,我想在myVideo.mp4完全加载后立即将videoLoaded分配给true。我可以在代码的最后几行这样做(这是我们的承诺): 第一个问题是,如果我们的URL无效,我们会得到一个404响应状态代码。404本身是一个有效的响应,因此我们不会触发xhr.onerror(),因为从技术上讲,它不是一个错误 我们可以使用以下工具跟踪404状态: xhr.onloadend = function() { if(xhr.status == 404) { // do something }

我想在
myVideo.mp4
完全加载后立即将
videoLoaded
分配给
true
。我可以在代码的最后几行这样做(这是我们的承诺):

第一个问题是,如果我们的URL无效,我们会得到一个
404响应状态代码
。404本身是一个有效的响应,因此我们不会触发
xhr.onerror()
,因为从技术上讲,它不是一个错误

我们可以使用以下工具跟踪404状态:

xhr.onloadend = function() {
    if(xhr.status == 404) { // do something }       
}
问题是仅在承诺
之后触发的
onloadend
事件。然后(items=>{..
因此,如果没有有效的URL,我们无法阻止承诺解析,
videoLoaded
将分配给
true
,尽管没有有效的URL

我想解决这个承诺,并将
videoLoaded
分配给
true
,前提是
xhr.status!==404
在这种情况下,我们可以确保我们有一个有效的URL

下面是代码(我使用了setInterval,它可以工作,但我认为有更干净的解决方案可以共享):

let onLoadPassed=false;
让videoLoaded=false;
让clipSource为您服务https://mysite/myVideo.mp4';
预加载();
//确保视频剪辑已完全加载
函数预加载(){
(功能(全球、工厂){
typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():
typeof define==“函数”&&define.amd?定义(工厂):
(global.Preload=factory());
}(这个,(函数(){'use strict';
函数1(url,完成){
const xhr=new XMLHttpRequest();
xhr.open('GET',url,true);
xhr.responseType='blob';
xhr.onprogress=事件=>{
如果(!event.lengthComputeable)返回false
让item=this.getItemByUrl(event.target.responseURL);
item.completion=parseInt((event.loaded/event.total)*100);
item.download=event.loaded;
item.total=event.total;
此.updateProgressBar(项目);
};
xhr.onload=事件=>{
let type=event.target.response.type;
让blob=newblob([event.target.response],{type:type});
让url=url.createObjectURL(blob);
让responseURL=event.target.responseURL;
让item=this.getItemByUrl(responseURL);
item.blobUrl=url;
item.fileName=responseURL.substring(responseURL.lastIndexOf('/')+1);
item.type=类型;
item.size=blob.size;
完成(项目);
};
xhr.onerror=事件=>{
log('发生错误,因此我们重新启动视频预加载…);
预加载();
};
xhr.onloadend=函数(){
如果(xhr.status==404){
console.log('404未找到');
onLoadPassed=false;
}否则{
log('File exist');
onLoadPassed=true;
}
}
xhr.send();
}
函数updateProgressBar(项){
var-sumpletion=0;
var maxCompletion=this.status.length*100;
for(此.status的var itemStatus){
if(itemStatus.completion){
sumpletion+=itemStatus.completion;
}
}
var totalCompletion=parseInt((sumpletion/maxCompletion)*100);
如果(!isNaN(全部完成)){
这是一个进步({
进度:全部完成,
项目:项目
});
}
}
函数getItemByUrl(rawUrl){
for(此状态的var项){
如果(item.url==rawUrl)返回项目
}
}
函数获取(列表){
返回新承诺((解决、拒绝)=>{
this.loaded=list.length;
对于(列表中的项目){
this.status.push({url:item});
这个。预加载一个(项目,项目=>{
此。已获取(项目);
这是我的;
如果(this.loaded==0){
this.oncomplete(this.status);
解决(此状态);
}
});
}
})
}
函数预加载(){
返回{
状态:[],
加载:false,
onprogress:()=>{},
完成:()=>{},
onfetched:()=>{},
取来
updateProgressBar,
第一,,
getItemByUrl
}
}
返回预载;
})));
常量预载=预载();
预加载.fetch([
clipSource
])。然后(项目=>{
//当我们确定视频剪辑已完全加载完毕时触发
let check=setInterval(passedFunc,50);
函数passedFunc(){
if(onLoadPassed==真){
videoLoaded=true;
清除间隔(检查);
console.log('videoLoaded:'+videoLoaded);
};
}
});   	

};
如果状态代码为404,您可以截取承诺并抛出错误,这样后续的
语句将被忽略,结果将被
.catch
语句捕获

preload.fetch([
  clipSource
])
.then(response => {
  if(!response.ok) //better to use response.ok as it checks a range of status codes
    throw Error(response.statusText); 
  return response;
})
.then(items => {
// Using a promise it'll fire when we are sure that video clip has finished loading completely
  videoLoaded = true;
})
.catch(error => {
  //do something
  console.log(error)
});

它首先进入,然后进入第二个
,然后进入第二个
??我看不出有错误…仍在尝试..检查状态代码是
404
。但是,请注意,
404
不是唯一的故障代码。我建议您检查
响应。改为“ok
”,它返回一个布尔值。ok
!response。ok
有效…我想告诉您响应是什么se记录日志,但它返回
Error:[object object]
…就在
之前,如果(!response.ok)抛出新错误(response.statusText);
您可以尝试改为记录
response
吗?您得到了什么?
preload.fetch([
  clipSource
])
.then(response => {
  if(!response.ok) //better to use response.ok as it checks a range of status codes
    throw Error(response.statusText); 
  return response;
})
.then(items => {
// Using a promise it'll fire when we are sure that video clip has finished loading completely
  videoLoaded = true;
})
.catch(error => {
  //do something
  console.log(error)
});