1

In this example, I want to return a pending "stop" Promise (1) which deletes an instance's reference to itself (1), and which callee may have pending / queued actions on.

In the case that a stop is currently happening, I want to return that existing, pending promise.

My question is whether or not the initial condition is deterministic and that it will always return a Promise; not undefined.

Since the variable / reference is removed upon completion, I'm curious if an async action could "jump in" between the conditional and the return statement, or if this is forbidden by block execution / precedence.

Thanks

stop () {
    if (this.awaitStop) {
        return this.awaitStop;

    } else {
        this.awaitStop = NativeDevice.video.stop(); // Promise
        return this.awaitStop.then(() => delete this.awaitStop);
    }
}
neaumusic
  • 10,027
  • 9
  • 55
  • 83
  • 2
    Rather than delete I would set it to null (performance), but this will work as intended... Did it few times – Akxe Mar 30 '18 at 00:37
  • This code may not behave as expected if the sequence `stop` `start` `stop` is performed in quick succession (the second stop returning the promise from the first stop, even though a start was called in the middle) – Paul S. Mar 30 '18 at 00:58
  • @PaulS. I believe the reference is removed before `start` is called, so the second stop would be a new promise. see the last line in the function -- which would happen before any consecutive chains – neaumusic Mar 30 '18 at 02:10
  • `this.p = new Promise.resolve(); this.p.then(() => delete this.p).then(() => console.log('p:' ,this.p))` – neaumusic Mar 30 '18 at 02:15
  • one thing to watch out for is multiple `.then()` off this initial promise, since `stop().then(play).then(stop)` will execute the second stop after any other `stop().then(myOtherChain)` – neaumusic Mar 30 '18 at 04:20

2 Answers2

2

Non-async functions do not get interrupted. Any callbacks will only be executed after all functions have returned and control flow returns to the "event loop".

Things would be different if you had an async function:

async function f() {
  if (foo) { 
    await bar();  // This interrupts f and lets any other code run.
    console.log(foo);  // foo may or may not be the same as before.
  }
}
jmrk
  • 34,271
  • 7
  • 59
  • 74
1

JavaScript has Run-To-Completion semantic, and is not multi-threaded in the conventional manner, as a standalone language (see here for examples where this could break depending on the environment).

What Run-To-Completion means for this example is that all synchronous code will run until finished and cannot be interrupted by any async call.

Only generators (with yield) and async functions (with await) can cause interuptions in JS and this has to be done explicitly (non-preemptive multitasking).

Since you do not have either in your code, your conditional will behave deterministically.

nem035
  • 34,790
  • 6
  • 87
  • 99