如何修改代码使Promise.all获取五次WSGeoTIFFAsBlobStreamer调用的全部响应
问题:Promise.all仅返回单个响应而非预期的5个结果
数组geoTIFFsFileNames包含5个文件名,需异步调用WebService WSGeoTIFFAsBlobStreamer五次,每次对应一个文件名并返回对应数据。创建promises数组收集.stream方法返回的Promise,执行await Promise.all(promises)后,.then中的response仅包含1个响应,而非预期的5个。
原代码
const promises = new Array(); promises.push(geoTIFFsFileNames.map((geoTIFFFileName, index) => { this.#geoTIFFOverlayBlobStreamingStates.value = GeoTIFFOverlayBlobStreamingStates.CONST_STREAMING.description; this.#wsGeoTIFFAsBlobStreamer = new WSGeoTIFFAsBlobStreamer(geoTIFFFileName); this.#wsGeoTIFFAsBlobStreamer.setRequestOptionsParams(); return this.#wsGeoTIFFAsBlobStreamer.stream((geoTIFFFileName, asBlob, asURL, state) => { this.#msg = ({msg:infoTag + 'connectWSGeoTIFFsAsBlobsStreamerFor().', url: `${endPointsURLs.VUE_NEWSWM_APP_LOCAL_HOST_3000.description}${endPointsURLs.VUE_NEWSWM_APP_PATH.description}${BackendWssConstants.CONST_WS_GEOTIFF_AS_BLOB_STREAMER.description}/${geoTIFFFileName}`, asBlob: asBlob, asURL: asURL, state: state, }); console.info(this.#msg); return [geoTIFFFileName, asBlob, asURL, state]; }) })); await Promise.all(promises) .then(response => { this.#msg = {msg:verboseTag + 'xcx connectWSGeoTIFFsAsBlobsStreamerFor().', response: response}; console.log(this.#msg); this.#geoTIFFOverlayBlobStreamingStates.value = GeoTIFFOverlayBlobStreamingStates.CONST_BLOB_OBTAINED.description; this.#setWSGeoTIFFAsBlobStreamerResults({ order: order, geoTIFFFileName: response[0], asBlob: response[1], asURL: response[2], state: response[3], }); resolve(response); onResult(response[0], response[1], response[2], response[3]); }) .catch(err => { this.#geoTIFFOverlayBlobStreamingStates.value = GeoTIFFOverlayBlobStreamingStates.CONST_ERROR_OCCURED.description; this.#msg = JSON.stringify({msg:WTFTag + 'connectWSGeoTIFFsAsBlobsStreamerFor.value. Error impeded ws from successful execution and return:', ws:BackendWssConstants.CONST_WS_GEOTIFF_AS_BLOB_STREAMER.description, geoTIFFsFileNames: geoTIFFsFileNames, error: err, }); console.error(this.#msg); reject({msg:errorTag + 'faild to fetch: ' + BackendWssConstants.CONST_WS_GEOTIFF_AS_BLOB_STREAMER.description + ' rejected promise', err:err}); onResult(null, null, null); throw new Error(this.#msg); });
问题根源
代码中使用promises.push(geoTIFFsFileNames.map(...)),map方法本身会返回一个包含5个Promise的数组,而push会把这个数组作为单个元素添加到promises中,最终promises变成嵌套数组(格式为[[promise1, promise2, promise3, promise4, promise5]])。Promise.all处理嵌套数组后,返回的response也会是嵌套结构,即包含结果数组的数组,而非直接由5个结果组成的数组。
解决办法
方案1:直接将map结果赋值给promises(推荐)
直接把map生成的Promise数组赋值给promises,避免嵌套:
const promises = geoTIFFsFileNames.map((geoTIFFFileName, index) => { this.#geoTIFFOverlayBlobStreamingStates.value = GeoTIFFOverlayBlobStreamingStates.CONST_STREAMING.description; this.#wsGeoTIFFAsBlobStreamer = new WSGeoTIFFAsBlobStreamer(geoTIFFFileName); this.#wsGeoTIFFAsBlobStreamer.setRequestOptionsParams(); return this.#wsGeoTIFFAsBlobStreamer.stream((geoTIFFFileName, asBlob, asURL, state) => { this.#msg = ({msg:infoTag + 'connectWSGeoTIFFsAsBlobsStreamerFor().', url: `${endPointsURLs.VUE_NEWSWM_APP_LOCAL_HOST_3000.description}${endPointsURLs.VUE_NEWSWM_APP_PATH.description}${BackendWssConstants.CONST_WS_GEOTIFF_AS_BLOB_STREAMER.description}/${geoTIFFFileName}`, asBlob: asBlob, asURL: asURL, state: state, }); console.info(this.#msg); return [geoTIFFFileName, asBlob, asURL, state]; }) });
方案2:使用扩展运算符展开push(推荐)
利用扩展运算符...将map生成的数组元素逐个添加到promises中,避免嵌套:
const promises = new Array(); promises.push(...geoTIFFsFileNames.map((geoTIFFFileName, index) => { // 原map内的代码保持不变 }));
方案3:在then中取出嵌套数组(不推荐)
如果不想修改promises数组的构建方式,可以在.then中手动取出嵌套的结果数组:
await Promise.all(promises) .then(response => { // 取出嵌套的结果数组 response = response[0]; // 后续逻辑处理 })
后续逻辑调整
修改后,Promise.all会返回包含5个响应的数组,需要调整.then中的处理逻辑,遍历整个结果数组来处理每个调用的返回值:
await Promise.all(promises) .then(responses => { this.#geoTIFFOverlayBlobStreamingStates.value = GeoTIFFOverlayBlobStreamingStates.CONST_BLOB_OBTAINED.description; responses.forEach((response, index) => { this.#setWSGeoTIFFAsBlobStreamerResults({ order: index, // 根据实际需求调整order值 geoTIFFFileName: response[0], asBlob: response[1], asURL: response[2], state: response[3], }); onResult(response[0], response[1], response[2], response[3]); }); resolve(responses); })
内容的提问来源于stack exchange,提问作者Amr
相关产品推荐
相关产品推荐

