简体   繁体   中英

Return a modfied object from a promise to async() block

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 , ie :

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM