I start a webworker (computing a hit into a game) into a promise and I would like to get back the results (always an array) once webworker has finished its computations.
I tried, at the end of promise, to return the object after the then(
and to do in main thread :
(async () => {
// Wait computeHit function
await computeHit(HitCurrent, 'computer');
But it seems when computation done by computeHit
is high, there are conflicts between return HitCurrent
from promise
and the HitCurrent = await
option into (async () =>
block.
It is clearer on the code below :
the background consists of :
1) the using of webworker
2) the using of promise
3) the async/await keywords
Promise block :
function computeHit(HitCurrent, mode) {
if (mode == 'computer') {
let HitTemp = JSON.parse(JSON.stringify(HitCurrent));
return new Promise( resolve => {
// Creation of webworker
firstWorker = new Worker(workerScript);
firstWorker.onmessage = function (event) {
resolve(event.data);
}
// Post current copy of HitCurrent, i.e HitCurrent
firstWorker.postMessage([HitTemp, HitTemp.playerCurrent, maxNodes]);
}).then(({result}) => {
// Get back game board of webworker
HitTemp = result.HitResult;
// Get back suggested hit computed by webworker
[a,b] = HitTemp.coordPlayable;
// Drawing all lines from suggested hit (in 8 directions)
// HERE, we modify HitCurrent attributes (like array)
for (k = 0; k < 8; k++) {
exploreHitLine(HitCurrent, a, b, k, 'drawing');
}
// Remove playable hits
cleanHits('playable', HitCurrent);
// Display current game
displayCurrentHit(HitCurrent);
// Return object HitCurrent
return HitCurrent;
})}
}
Async block waiting for promise above is :
(async () => {
// Wait computeHit function and update HitCurrent when promise is done
HitCurrent = await computeHit(HitCurrent, 'computer');
// Reset, switch and update
resetSwitchUpdate(HitCurrent, false);
})();
I would like to get the updated HitCurrent
object (modified as I said into exploreHitLine(HitCurrent, a, b, k, 'drawing');
) and this, once webworker has received its results (a value and an object HitResult).
I don't know how to make the behavior of await computeHit(HitCurrent, 'computer');
and the return that I apply the end of Promise
, i.e :
return HitCurrent;
What is the correction solution ? :
1) doing :
(async () => {
// Wait computeHit function and update HitCurrent when promise is done
await computeHit(HitCurrent, 'computer');
with into Promise
:
return HitCurrent;
2) doing :
(async () => {
// Wait computeHit function and update HitCurrent when promise is done
Object = await computeHit(HitCurrent, 'computer');
with into Promise
:
return HitCurrent;
for 2) case, if this is the solution, how can I get back the Hitcurrent
object from local variable Object
? I saw that result may be a wrapper.
I think an important point is that returning a promise is different from returning an Object like HitCurrent
, isn't it ?
For the moment, for light computation into webworker, solution given in the code section of this post works fine but as soon as I have high computation for webworker, the code terminates itself the game, without no more interactions for the user hit (that I do with mouse click on game board).
So, I would like to get advices to get back the object HitCurrent
from Promise
block in all cases, for light and high computation of webworker.
ok, after looking at the demo I think I see a reason why it might be breaking..
You have currentGame
function with multiple cases for the game mode (user / computer, etc), and for computer mode you are calling that function that returns promise. The problem is that promise is wrapped in immediately invoked function which means that the code below it doesn't wait and keeps executing.
Just to illustrate what I mean, here's an example for you:
var testPriomise = () => new Promise(resolve => { resolve(2)})
console.log('1');
(async() => {
var result = await testPriomise();
console.log(result)
})()
console.log('Look! I fire before 2!', 3)
If you run it in console you'll notice that it logs 1, 3 and only then 2. I hope that you see where I'm going with it:)
Make these few changes: Instead of
// Main game function : started with white player
function currentGame(HitCurrent) {
do
// Main game function : started with white player
async function currentGame(HitCurrent) {
And for your computer mode case do this :
// Play computer hit
else {
// First option : Wait computeHit function
await computeHit(HitCurrent, 'computer');
// Reset, switch and update
resetSwitchUpdate(HitCurrent, false);
}
This way you ensure that the resetSwitchUpdate
has updated HitCurrent
object.
I hope this will fix it!