#javascript #angular #promise #rxjs #observable
#javascript #angular #обещание #rxjs #наблюдаемый
Вопрос:
У меня есть следующий фрагмент кода, в основном я пытаюсь загрузить фрагменты большого файла на подписанные URL-адреса, возвращаемые из службы..
Мне нужно вызвать конечную точку uploadcompleted только после завершения всех запросов PUT в возвращенном forkjoin, но проблема, с которой я сталкиваюсь, заключается в том, что я не могу дождаться загрузки фрагментов на подписанный URL.
Что я здесь делаю не так? Любая помощь будет высоко оценена. Заранее спасибо.
filechunks(chunk: any, uploadUrls: string[], index) {
let observableBatch = [];
const headers: HttpHeaders = new HttpHeaders({
'content-type': 'application/json'
});
observableBatch.push(this._http.put<any>(uploadUrls[index], chunk, { headers }))
return forkJoin(observableBatch).pipe(delay(1000));
// const createRequest = () => of(this._http.put<any>(uploadUrls[index], chunk, { headers }));
// return forkJoin(createRequest).pipe(delay(1000));
}
uploadfileinchunks(uniqueFileId: string, uploadId: string, chunks, uploadUrls): Observable<any> {
let response = [];
chunks.map( (chunk, i) => {
let response = this.filechunks(chunk, uploadUrls, i).toPromise();
console.log(response)
});
const params = {
some-id: some-id
};
return this._http.post<FileData>(
`${somurl}/uploadcompleted`,
{},
{ {}, params }
);
}
Комментарии:
1. this.filechunks(chunk, uploadUrls, i).toPromise(); это будет выполняться асинхронно, и uploadfilechunks запустит post немедленно, не дожидаясь
Ответ №1:
Интерпретация:
Ваш код на самом деле не имеет смысла, поэтому трудно понять, что вы даже пытаетесь сделать
filechunks(chunk: any, uploadUrls: string[], index) {
const headers: HttpHeaders = new HttpHeaders({
'content-type': 'application/json'
});
// observableBatch is an array of size 1. Why bother?
const observableBatch = [];
observableBatch.push(
this._http.put<any>(
uploadUrls[index],
chunk,
{ headers }
)
);
// You're runnung forkJoin on a single observable? Again, why?
return forkJoin(observableBatch).pipe(delay(1000));
}
uploadfileinchunks(uniqueFileId: string, uploadId: string, chunks, uploadUrls): Observable<any> {
// Here, response is declared, but it's never used. You can delete this.
let response = [];
// chunks#map is a mapping function, but you're mapping every element to
// null. Maybe what you mean is forEach?
chunks.map( (chunk, i) => {
// This a new response, this one is a promise. If you want the result
// returned from filechunks, you'd need to resolve this promise
// with response.then(LAMBDA) or await response
// Also, mixing observables and promises is often a code smell.
let response = this.filechunks(chunk, uploadUrls, i).toPromise();
// You're logging a promise object here, not its resolved value
console.log(response)
});
// Not sure what this is?
const params = {
some-id: some-id
};
// call the uploadcompleted endpoint, but you haven't waited
// for your other calls to complete. That's what this question is about.
return this._http.post<FileData>(
`${somurl}/uploadcompleted`,
{},
{ {}, params }
);
}
Мое лучшее предположение о том, что ты собирался сделать:
Я, очевидно, не могу это проверить, и в любом случае он неполный, поскольку ваш вопрос довольно расплывчатый, но, может быть, это приведет вас по правильному пути?
Помните, что uploadfileinchunks
возвращает наблюдаемый объект, а наблюдаемые объекты ничего не делают до тех пор, пока вы subscribe
. Поэтому, где бы ни вызывался этот код, вам нужно обязательно это делать.
filechunks(chunk: any, uploadUrls: string[], index) {
return this._http.put<any>(
uploadUrls[index],
chunk,
{
headers: new HttpHeaders({
'content-type': 'application/json'
})
}
).pipe(
delay(1000)
);
}
uploadfileinchunks(uniqueFileId: string, uploadId: string, chunks, uploadUrls): Observable<any> {
return forkJoin(chunks.map(
(chunk, i) => this.filechunks(chunk, uploadUrls, i)
).pipe(
map(response => ({
some-id: "some-id"
})),
switchMap(params => this._http.post<FileData>(
`${somurl}/uploadcompleted`,
{},
{ {}, params }
))
);
}