【发布时间】:2018-02-25 12:28:15
【问题描述】:
我有一个比较简单的 HTTP PUT 请求:
const req = new HttpRequest('PUT', payload.url, payload.file, {
reportProgress: true,
headers: new HttpHeaders().set('Content-Type', 'image/jpeg'),
});
return self.http.request(req).subscribe((event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Sent:
console.log('Request sent!');
break;
case HttpEventType.ResponseHeader:
console.log('Response header received!');
break;
case HttpEventType.DownloadProgress:
const kbLoaded = Math.round(event.loaded / 1024);
console.log(`Download in progress! ${kbLoaded}Kb loaded`);
break;
case HttpEventType.UploadProgress:
const kbUploaded = Math.round(event.loaded / 1024);
console.log(`Upload in progress! ${kbUploaded}Kb loaded`);
break;
case HttpEventType.Response:
console.log('???? Done!', event.body);
return payload;
}
});
如何将其插入可观察的流中,以便我可以将之前的响应通过管道传输到其中并等待发送下一个响应,直到上传完成?我尝试了以下方法:
- 将整个内容包装在
.do(payload => { ... } )中
这种工作——语句按预期触发,文件被上传——但下游的函数不会等到上传完成,所以我不能以任何方式传递结果。这也让人觉得很老套,因为文档暗示 .do() 更多地用于日志记录和次要实用程序,而不是整个功能的核心任务。
- 使用
map和flatMap尝试将其放入流中
我还尝试将请求功能拆分为如下几个函数:
...
.flatMap(payload => {
const req = new HttpRequest('PUT', payload.url, payload.file, {
reportProgress: true,
headers: new HttpHeaders().set('Content-Type', 'image/jpeg'),
});
return self.http.request(req).map((event: HttpEvent<any>) => {
return { ...payload, event };
});
})
.map(payload => {
switch (payload.event.type) {
case HttpEventType.Sent:
console.log('Request sent!');
break;
case HttpEventType.ResponseHeader:
console.log('Response header received!');
break;
case HttpEventType.DownloadProgress:
const kbLoaded = Math.round(payload.event.loaded / 1024);
console.log(`Download in progress! ${kbLoaded}Kb loaded`);
break;
case HttpEventType.UploadProgress:
const kbUploaded = Math.round(payload.event.loaded / 1024);
console.log(`Upload in progress! ${kbUploaded}Kb loaded`);
break;
case HttpEventType.Response:
console.log('???? Done!', payload.event.body);
return [];
}
})
上传有效,但 observable 最终会为每个 HttpEvent 发送响应,这不是我想要的。我只想在上传完成后发送回复,也就是HttpEventType.Response。
我做错了什么,我该如何做对?
【问题讨论】:
-
在你的 2 号 sn-p 中的最后一个
map之后你有什么?可能是您发生了错误,因为除了HttpEventType.Response之外的所有情况都会看到undefined从map发出并进入可观察流。 -
我有一个
map函数来检查是否所有提供的文件都已上传,如果是则返回结果。我尝试将其注释掉并仅返回一个空变量,然后请求开始通过。在if块中放置return语句是否会以某种方式破坏流? -
这个问题很难理解。我认为您需要添加所有相关代码。
-
我不知道其他相关代码应该是什么样子,因为我不知道如何构造这种 observable。这就是我问这个问题的原因。话虽如此,删除 sn-p 2 之后的所有内容并仅返回一个空数组(整个 observable 用于变量数组)使请求工作,但我想过滤事件以便它仅在上传时响应已完成。
标签: angular typescript rxjs