1

I'm removing content (a div) but first waiting for an animation (if none is provided, then the animation is just a resolved Promise by default). Check this out:

clearContent = (animation = Promise.resolve()) => {
  return new Promise((resolve, reject) => {

    const child = $('#child');

    animation.then(animationEvent => {
      const eventPackage = {
        'divRemoved': 'divIDPlaceholder',
        'itemRemoved': 'contentIDPlaceholder',
        'remainingItemsCount': 2,
        'remainingItems': 1
      };

      child.remove();

      const contentRemovedEvent = new CustomEvent('contentRemovedFromPlaceholder', {
        'detail': eventPackage
      });
      window.dispatchEvent(contentRemovedEvent);

      console.log('Removed!');

      return resolve(eventPackage);
    });
  });
}

const testAnimationThatTakesASecond = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      return resolve()
    }, 1000);
  });
}

$('#child').on('click', () => {
  clearContent(testAnimationThatTakesASecond());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="child">Remove me! The removal process can be animated as well!</div>

My constraints are that I'm waiting on an animation by anime.js and I'd like the whole removal process (that is the animation + the removal of the div itself) to be dependable on, because I might choose to chain some things based on it..

The problem is that although this is a wrapper function, I sometimes find that it doesn't work properly on low CPU. I'm thinking maybe because the .remove itself removes after the promise itself is resolved.

Am I wrong to think that a Promise will always wait for whatever code it has inside to finish?

coolpasta
  • 725
  • 5
  • 19
  • i don't sure how works your animation effect, but if you want make a little delay on your `setTimeout` function you should to use `async` `await` for wait to resolve the `promise` – Christian Carrillo Oct 26 '19 at 17:28
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Oct 26 '19 at 18:11
  • @Bergi I gave up on it or rather things I really just don't understand, people will say "avoid the anti-pattern"...but how? I wanted to write the best code that I could but your time is limited and although there's no deadline, products have to go out. This is a thing I don't understand, the code works for my what I need it to work, so, I'll take a bigger look afterwards. – coolpasta Oct 26 '19 at 18:13
  • Your code does not work when the `animation` promise rejects. – Bergi Oct 26 '19 at 18:16
  • @Bergi That's just for the sake of the example. People don't bother reading if example code is the length of a book. – coolpasta Oct 26 '19 at 18:17
  • @coolpasta If you don't post your real code, we can't tell you the real issues. Btw avoiding the promise constructor antipattern and using `then` chaining would actually make the code even shorter (in addition to making it more correct) – Bergi Oct 26 '19 at 18:19
  • @Bergi It's literally the same code right here without all the checks & specifics to my code. In fact, people should learn to post concise code in their questions. Here's my code: http://prntscr.com/poijev . The details contained here don't help anybody but just make it harder for people to read through. – coolpasta Oct 26 '19 at 18:21
  • @Bergi I would if I knew how, but every time somebody tells me about it, they don't show me how to. I kind of get what they mean but then again, I don't. I've never seen a few examples of "anti-pattern vs. well written" to be able to deduce. I guess my intelligence stops there :P . Tried reading about it, watched the talks but it just doesn't stick. – coolpasta Oct 26 '19 at 18:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201455/discussion-between-coolpasta-and-bergi). – coolpasta Oct 26 '19 at 18:36

2 Answers2

0

Your function is fine, but from your last sentence and comments it seems like your expectation about promises is not quite correct.

If you are calling the code like this:

clearContent(testAnimationThatTakesASecond());
console.log('something after resolved');

The console.log will be executed before the animation finishes. The execution will not be halted in the calling context.

If you need to do something after the animation is resolved you need to use it like this:

clearContent(testAnimationThatTakesASecond())
    .then(() => console.log('something after resolved'));

Or using async:

$('#child').on('click', async () => {
    await clearContent(testAnimationThatTakesASecond());
    console.log('something after resolved');
});
Thiago Barcala
  • 6,463
  • 2
  • 20
  • 23
-1

When you put async in front of a function you're telling that it will return a promise with the value from the return statement resolved! When you await you're waiting for the promise to be fulfilled.

   $('#child').on('click',async () => {
          await testAnimationThatTakesASecond();
          clearContent();
      });

Edit:With promises also, we can use then to make sure that promise is resolved, and just then run the second phase.
Depend on our desired asynchronous order for our callbacks to get execute, if our they where doSomething() and doSomethingElse() to get them execute in order we can use

doSomething().then(doSomethingElse)

This is the only way that we are able to use the result of doSomething, inside doSomethingElse, It's like we ran: doSomethingElse(resultOfDoSomething):

And also It's then-able in the way that if we had third operation, it get called after doSomethingElse finishes like: finalHandler(resultOfDoSomethingElse)

Nima Bastani
  • 185
  • 11
  • Hold on. My question is about combining synch + async code together and how it all works and why my issue occurs. – coolpasta Oct 26 '19 at 17:32
  • 1
    I spend an hour on this, reading more about it and I think mixing `async/await` with `Promise` is confusing and yet practical. both of them return a promise! That is the connection between async/await and promises. When you put async in front of a function you're telling that it will return a promise with the value from the return statement resolved! When you await you're waiting for the promise to be fulfilled, in this case, it is the same as calling the .then from the returned promise! – Nima Bastani Oct 26 '19 at 18:58