gpt4 book ai didi

typescript - 可观察和 xhr.upload.onprogress 事件

转载 作者:太空狗 更新时间:2023-10-29 17:52:56 26 4
gpt4 key购买 nike

我有两个服务。

1) UploadService - 通过 ajax 将文件发送到服务器,同时获取并存储进度值(在 xhr.upload.onprogress 事件处理程序中)

2) SomeOtherService 使用 DOM,从第一个服务获取进度值,将其显示在 Bootstrap 进度条上。

因为,xhr.upload.onprogress 是异步的 - 我在第一个服务中使用了 Observable:

constructor () {
this.progress$ = new Observable(observer => {
this.progressObserver = observer
}).share();
}

private makeFileRequest (url: string, params: string[], files: File[]): Promise<any> {
return new Promise((resolve, reject) => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();

for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}

xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.response);
}
}
};

xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);

this.progressObserver.next(this.progress);
};

xhr.open('POST', url, true);
xhr.send(formData);
});
}

在第二个服务中,我订阅了这个观察者:

this.fileUploadService.progress$.subscribe(progress => {
this.uploadProgress = progress
});

this.fileUploadService.upload('/api/upload-file', [], this.file);

现在我的问题:

该代码不起作用。在第二项服务中,我仅获得一次观测值,即 100%。

但是如果我插入(是的,回调主体为空)

setInterval(() => {
}, 500);

在 makeFileRequest 方法中 - 我将每 500 毫秒在第二个服务中获取进度值。

private makeFileRequest (url: string, params: string[], files: File[]): Promise<any> {
return new Promise((resolve, reject) => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();

for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}

xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.response);
}
}
};

setInterval(() => {
}, 500);

xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);

this.progressObserver.next(this.progress);
};

xhr.open('POST', url, true);
xhr.send(formData);
});
}

那是什么?为什么会这样?我如何在没有 setInterval 的情况下通过 onprogress 事件正确使用 Observable?

UPD:Thierry Templier 在里面回答之后

this.service.progress$.subscribe( data => { 
console.log('progress = '+data);
});

我得到了正确的值,但是这些值没有在模板中动态更新,只是再次更新为 100%。

最佳答案

我没有完整的代码,所以很难给你一个准确的答案。

事实上,您说“在第二次服务中,我只获得一次观察值,100%。”让我觉得它应该与 promise 的使用有关。事实上, promise 可以被解决或拒绝一次。不支持与 observables 相反的多个事件。

如果你可以发布一个 plunkr 和你的代码,我将能够调试它,所以我应该为你提供更准确的答案。

编辑

我创建了一个 plunkr ( http://plnkr.co/edit/ozZqbxIorjQW15BrDFrg?p=preview ) 来测试您的代码,它似乎可以正常工作。通过将 promise 更改为 observable,我获得了更多进度提示。

makeFileRequest(url: string, params: string[], files: File[]): Observable> {
return Observable.create(observer => {
let formData: FormData = new FormData(),
xhr: XMLHttpRequest = new XMLHttpRequest();

for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}

xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
observer.next(JSON.parse(xhr.response));
observer.complete();
} else {
observer.error(xhr.response);
}
}
};

xhr.upload.onprogress = (event) => {
this.progress = Math.round(event.loaded / event.total * 100);

this.progressObserver.next(this.progress);
};

xhr.open('POST', url, true);
xhr.send(formData);
});
}

这是我的痕迹:

app.component.ts:18 progress = 21
app.component.ts:18 progress = 44
app.component.ts:18 progress = 71
app.component.ts:18 progress = 100

有了 promise ,我只得到了两条痕迹

关于typescript - 可观察和 xhr.upload.onprogress 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35279787/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com