/    Sign up×
Community /Pin to ProfileBookmark

Multiple Promises and/or Async Functions

I’m greeting everyone,

after learning more about NodeJS and mysql, i run into synchronizing problems. I want to avoid using async&await and to rarely use try&catch instead keep on .then() and .catch(), but I having my issues with multiple _async_ functions (sql queries), especially if they are called inside another .then() because I need to loop through sql results. The return of getPlayerSubjects() is executed before its arrays/objects are filled with subqueries. How to synchronize it, so that the .then() after getPlayerData() can use the db data? Maybe I’m too new to Promises and asynchronous functions.

Here is the relevant code:

“`
const playersData = {};
const subjectFactors = {};
const dbpool = mysql.createPool({…, multipleStatements:true});

function query(sql) {
return new Promise((resolve, reject) =>{
try {
dbpool.query(sql, (err, result) => {
if (err){
return reject(err)
}

return resolve(result)
});
}
catch(event) {
reject(event)
}
})
}

function getPlayerSubjects(request, subjectResults) {
const playerSubjects = {};

for(const subjectResult of subjectResults) { // for all units
if(subjectResult.boolval) { // simple boolean evaluation
query(‘SELECT * FROM ranks WHERE rank_id=’+subjectResult.start+’;’
+’ SELECT * FROM ranks WHERE rank_id=’+subjectResult.end)
.then((startEndResults) => { // when both sqls done
if(breaksThreshold(playerRank, (startEndResults[1][0].position-startEndResults[0][0].position)*subjectResult.part) { // simple function evaluation
subjectResult[‘subject_subs’] = [];
playerSubjects[subjectResult[‘subject_id’]] = query(‘SELECT * WHERE subsubject_subject_id=’+subjectResult[‘subject_id’])
.then((subsubjectResults) => {
for(const subsubjectResult of subsubjectResults) {
updateFactorsOfPlayer(subjectResult[‘subject_player_id’], subsubjectResult[‘subsubject_subject_id’],);
subjectResult[‘subject_subs’].push(subsubjectResult);
}
});
playerSubjects[subjectResult[‘subject_id’]] = subjectResult;
}
});
}
}

return {subjects:playerSubjects, subjectFactors:subjectFactors};

function getPlayerData(request, playerResults) {
return {friends:getPlayerFriends(request, playerResults[0]), …getPlayerSubjects(request, playerResults[1])}; // build event data structure
}

function sendPlayerEvent(request, response) {
query(‘SELECT * FROM ranks’
+’; SELECT * FROM subjects’)
.then((playerResults) => {
getPlayerData(request, playerResults)
.then((currentPlayerData) => {
if(notEqual(playersData[request.query.id], currentPlayerData)) { // data has changed
playersData[request.query.id] = currentPlayerData; // set new player data
response.write(`data: ${JSON.stringify({player:playersData[request.query.id]})}nn`);
}
});
})
.catch((error) => {
console.error(error);
});
}
“`

to post a comment

7 Comments(s)

Copy linkTweet thisAlerts:
@sibertAug 13.2022 — Maybe you can let the database do all the fetching in one step. Either using CTE (WITH) or UNION ALL.

``<i>
</i>SELECT * FROM ranks WHERE rank_id=subjectResult.start
UNION ALL
SELECT * FROM ranks WHERE rank_id=subjectResult.end
UNION ALL
SELECT * FROM ranks WHERE something else.<i>
</i>
`</CODE>
optionally you can use CTE
<CODE>
`<i>
</i>WITH list AS (SELECT whatever you want and JOIN whatever)
SELECT * FROM list<i>
</i>
``

WITH works with modern databases.
Copy linkTweet thisAlerts:
@AtsutakeauthorAug 13.2022 — Thank you, I will look into it :)
Copy linkTweet thisAlerts:
@SempervivumAug 13.2022 — @Atsutake#1645912
>I want to avoid using async&await

For what reason? I'm not familiar with nodejs but clientside javascript and there async-await makes it very easy to ensure a certain sequence of asynchronous actions. Without nested structures of `then`. I expect that the situation is very similar in nodejs.
Copy linkTweet thisAlerts:
@AtsutakeauthorAug 14.2022 — I might be wrong, but this is what I understood: I'm using sendPlayerData as interval of SSE and this way the code is clearer&shorter for me, because I can use .catch() instead of try&catch (= prefered when you use await), so sendPlayerData(), the interval function of SSE, don't have to be async. Also wouldn't await cause whole JS to pause instead of using the time to work on more functions which don't need to be serialized?

Is there a way to await {friends:getPlayerFriends(request, playerResults[0]), ...getPlayerSubjects(request, playerResults[1])} or do I have to await them separately, store in variable and then build object struture. I would prefer to not store in variable, if someone knows how.
Copy linkTweet thisAlerts:
@SempervivumAug 14.2022 — I have to admit, that I didn't take into account error handling in my posting. However there is an example on MDN:

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises#async_and_await

The same advantage: Multiple requests keeping the desired sequence without nesting of `then`.

However I'm not sure if this is the same in nodejs.
Copy linkTweet thisAlerts:
@AtsutakeauthorAug 16.2022 — I recoded to async-await and it works now.
Copy linkTweet thisAlerts:
@finchloe121Aug 16.2022 — My Website Will Not Load Properly Can Anyone Will Help. https://www.pharmacymedsonline.com/
×

Success!

Help @Atsutake spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 4.20,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...