[英]Why is it not waiting for an awaited Promise.all to resolve?
我以前的工作代码在可迭代的每个元素上调用等待效率低下。 我正在重构以使用 Promise.All。 但是,我的代码没有等待 Promise.All 在执行进一步代码之前解决。
具体来说, purgeRequestPromises
行在初始Promise.All
解析之前执行。 我不确定这是为什么? retrieveSurrogateKey
是一个异步 function,所以它的返回行将被包裹在一个已解析的 promise 中。
try {
//retrieve surrogate key associated with each URL/file updated in push to S3
const surrogateKeyPromises = urlArray.map(url => this.retrieveSurrogateKey(url));
const surrogateKeyArray = await Promise.all(surrogateKeyPromises).catch(console.log);
//purge each surrogate key
const purgeRequestPromises = surrogateKeyArray.map(surrogateKey => this.requestPurgeOfSurrogateKey(surrogateKey));
await Promise.all(purgeRequestPromises);
// GET request the URLs to warm cache for our users
const warmCachePromises = urlArray.map(url => this.warmCache(url));
await Promise.all(warmCachePromises)
} catch (error) {
logger.save(`${'(prod)'.padEnd(15)}error in purge cache: ${error}`);
throw error
}
async retrieveSurrogateKey(url) {
try {
axios({
method: 'HEAD',
url: url,
headers: headers,
}).then(response => {
console.log("this is the response status: ", response.status)
if (response.status === 200) {
console.log("this is the surrogate key!! ", response.headers['surrogate-key'])
return response.headers['surrogate-key'];
}
});
} catch (error) {
logger.save(`${'(prod)'.padEnd(15)}error in retrieveSurrogateKey: ${error}`);
throw error
}
}
我知道 purgeRequestPromises 提前执行,因为我收到错误消息,抱怨我在 HEAD 请求中将代理密钥 header 设置为undefined
:
async requestPurgeOfSurrogateKey(surrogateKey) {
headers['Surrogate-Key'] = surrogateKey
try {
axios({
method: `POST`,
url: `https://api.fastly.com/service/${fastlyServiceId}/purge/${surrogateKey}`,
path: `/service/${fastlyServiceId}/purge${surrogateKey}`,
headers: headers,
})
.then(response => {
console.log("the status code for purging!! ", response.status)
if (response.status === 200) {
return true
}
});
} catch (error) {
logger.save(`${'(prod)'.padEnd(15)}error in requestPurgeOfSurrogateKey: ${error}`);
throw error;
}
}
retrieveSurrogateKey
同步返回undefined
: try
块中的值是 promise 并且没有同步抛出错误,因此从不执行catch
子句并且执行落到底部,从 function 主体返回undefined
。
您可以尝试以下方法:
function retrieveSurrogateKey(url) { // returns a promise
return axios({
// ^^^^^^
method: 'HEAD',
url: url,
headers: headers,
}).then(response => {
console.log("this is the response status: ", response.status)
if (response.status === 200) {
console.log("this is the surrogate key!! ", response.headers['surrogate-key'])
return response.headers['surrogate-key'];
}
}).catch(error => {
logger.save(`${'(prod)'.padEnd(15)}error in retrieveSurrogateKey: ${error}`);
throw error;
});
}
请注意,如果 function 返回一个 promise 作为async
,则声明它是多余的,如果它不使用await
。 这一行还有一个次要问题:
const surrogateKeyArray = await Promise.all(surrogateKeyPromises).catch(console.log);
除非重新抛出错误,否则catch
子句将完成 promise 链。 您可以(也许)放弃.catch
子句或将其重新编码为
.catch( err=> { console.log(err); throw err} );
您不必为了让它工作而从retrieveSurrogateKey()
中删除async
。 事实上,如果你不这样做,它更具可读性。 正如已经解释的那样,问题是retrieveSurrogateKey()
返回的 promise 没有跟随调用axios()
返回的 promise 的完成。 你需要await
它:
async retrieveSurrogateKey(url) {
try {
const response = await axios({
method: 'HEAD',
url,
headers,
});
console.log('this is the response status: ', response.status);
if (response.status === 200) {
const surrogateKey = response.headers['surrogate-key'];
console.log('this is the surrogate key!! ', surrogateKey);
return surrogateKey;
}
} catch (error) {
logger.save(`${'(prod)'.padEnd(15)}error in retrieveSurrogateKey: ${error}`);
throw error;
}
}
这保留了您当前拥有的相同逻辑,但您会注意到,当response.status !== 200
时,您最终会得到undefined
的已解决 promise,而不是被拒绝的 promise。 您可能希望使用validateStatus
来断言 200 的确切状态。默认情况下,axios 解析任何状态 >= 200 且 < 300 的响应:
async retrieveSurrogateKey(url) {
try {
const response = await axios({
method: 'HEAD',
url,
headers,
validateStatus(status) {
return status === 200;
}
});
const surrogateKey = response.headers['surrogate-key'];
console.log('this is the surrogate key!! ', surrogateKey);
return surrogateKey;
} catch (error) {
logger.save(`${'(prod)'.padEnd(15)}error in retrieveSurrogateKey: ${error}`);
throw error;
}
}
这样,您始终可以保证使用代理键或被拒绝的 promise。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.