How Can Asynchronous Method In Recursion Return Result Correctly?
Solution 1:
Wrapping GetDynamodb(UID)
in a new Promise
is an anti-pattern since it returns a promise.
Following adds a retries
parameter with a default to CallGetDB()
and either returns a new promise in the catch()
when retries are within limits.... or throws a new error to get caught in following catch()
letsleep = ms => newPromise(r =>setTimeout(r, ms));
functionCallGetDB(UID, retries = 0) {
returnGetDynamodb(UID)
.catch((data) => {
if (retries++ < 2) {
console.log("This is " + (retries + 1) + " try to get data from db with UID.");
// return another promisereturnsleep(100).then(() =>CallGetDB(UID, retries));
} else {
console.log("Database multi fetch failed");
// throw error to next catch()thrownewError("Database multi fetch failed");
}
});
}
SendSQS(UID, event).then((data) => {
returnCallGetDB(data);
}).then((data) => {
console.log("Data Success:" + JSON.stringify(data));
response.body = JSON.stringify(data);
callback(null, data);
}).catch(err =>/* do something when it all fails*/ );
Solution 2:
Your promise isn't resolving in the event of an error and an index
lower than 2. Here:
if(index++ < 2){
console.log("This is "+(index+1)+" try to get data from db with UID.");
setTimeout(function(){CallGetDB(UID);},100);
}
At that point, your promise will never fulfill or reject as the original promise never gets fulfilled and can't resolve
the JSON data nor does it hit your else
branch.It becomes an unresolved promise (a promise stalled indefinitely). It will work in the event that GetDynamodb
fulfills on the first attempt though.
You can fix this by fulfilling the promise inside the if
branch:
setTimeout(function(){resolve(CallGetDB(UID));},100);
That being said, you probably shouldn't be wrapping promises like this. This is a somewhat similar approach to yours:
letdelay = ms => newPromise(r =>setTimeout(r, ms));
functionCallGetDB(UID) {
returnGetDynamodb(UID).then(data => {
console.log("check before if"+JSON.stringify(data));
return data;
}).catch(err => {
if(index++ < 2){
console.log("This is "+(index+1)+" try to get data from db with UID.");
returndelay(100).then(() =>CallGetDB(UID));
} else {
console.log("Database multi fetch failed");
return"Database multi fetch failed";
}
});
});
You can also use a closure for scoping retries, so you have a proper scope for your index
variable:
letdelay = r => newPromise(r =>setTimeout(r, ms));
functionCallGetDB(retries) {
let index = retries;
returnfunctioninner(UID){
returngetDynamodb(UID).then((data)=> {
console.log("check before if"+JSON.stringify(data));
return data;
}).catch(err => {
if(index--){
console.log("This is "+(retries-index)+" try to get data from db with UID.");
returndelay(100).then(() =>inner(UID));
} else {
console.log("Database multi fetch failed");
return"Database multi fetch failed";
}
});
};
}
Which you can now use like: CallGetDB(2)(data)
Post a Comment for "How Can Asynchronous Method In Recursion Return Result Correctly?"