Ole*_*ann 2 javascript node.js promise async-await
我正在尝试从数据库中获取记录。由于竞争条件,当我第一次尝试获取记录时,记录可能甚至可能不存在。我如何将其包装在重试逻辑中而不发疯?我似乎太愚蠢了
const booking = await strapi.query("api::booking.booking").findOne({
where: {
id: id,
},
});
Run Code Online (Sandbox Code Playgroud)
此代码应n延迟几t毫秒重试。谢谢并充满爱意。
我尝试过的:
async function tryFetchBooking(
id,
max_retries = 3,
current_try = 0,
promise
) {
promise = promise || new Promise();
// try doing the important thing
const booking = await strapi.query("api::booking.booking").findOne({
where: {
id: id,
},
});
if (!booking) {
if (current_try < max_retries) {
console.log("No booking. Retrying");
setTimeout(function () {
tryFetchBooking(id, max_retries, current_try + 1, promise);
}, 500);
} else {
console.log("No booking. Giving up.");
promise.reject(new Error("no booking found in time"));
}
promise.catch(() => {
throw new Error(`Failed retrying 3 times`);
});
} else {
console.log("Found booking with retry");
promise.resolve(booking);
}
}
const booking = await tryFetchBooking(id);
Run Code Online (Sandbox Code Playgroud)
抛出的错误:
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
TypeError: Promise resolver undefined is not a function
Run Code Online (Sandbox Code Playgroud)
这种promise.reject()方法promise.resolve()是行不通的,你无法解决来自外部的承诺。而且你不应该需要 - 只需return/throw来自你的async函数!唯一需要构造 a 的地方new Promise是一个小辅助函数
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
Run Code Online (Sandbox Code Playgroud)
然后你可以以递归方式编写你的函数:
async function tryFetchBooking(
id,
max_retries = 3,
current_try = 0,
) {
let booking = await strapi.query("api::booking.booking").findOne({
where: {
id: id,
},
});
if (!booking) {
if (current_try < max_retries) {
console.log("No booking. Retrying");
await delay(500);
// ^^^^^^^^^^^^^^^^
booking = await tryFetchBooking(id, max_retries, current_try + 1);
// ^^^^^^^^^^^^^^^^^^^^^
console.log("Found booking with retry");
} else {
console.log("No booking. Giving up.");
throw new Error("no booking found in time");
// or if you prefer the other error message:
throw new Error(`Failed retrying 3 times`);
}
}
return booking;
}
Run Code Online (Sandbox Code Playgroud)
甚至以迭代的方式:
async function tryFetchBooking(id, maxRetries = 3) {
let currentTry = 0;
while (true) {
const booking = await strapi.query("api::booking.booking").findOne({
where: {
id: id,
},
});
if (booking) {
return booking;
}
if (currentTry < maxRetries) {
await delay(500);
currentTry++;
} else {
console.log("No booking. Giving up.");
throw new Error("no booking found in time");
}
}
}
Run Code Online (Sandbox Code Playgroud)