0

What's expected to happen with running Javascript promises when my system sleeps and then get back to the resume state?

Let's suppose that I have a Javascript application that is running and there are some promises doing their asynchronous work (as requesting data from a remote endpoint), so I'm put my OS on sleep mode and go away. After some time, I get back and resume my system. Would those promises continue running after that? Can I assume that either the "then" or "catch" will be called for each of them or is it possible to get some zombie promises that will never return?

It would be great if the answer comes together with some source to basis it =)

Valmir
  • 401
  • 1
  • 5
  • 14
  • Kind of undefined. Depends on what the asynchronous operation *is* - that one might throw or who knows. However, from just normal JS perspective...should be fine, AFAIK. Sleeping suspends everything then restores it. Chances are that everything will just continue. However, your *application state* might be jumbled. Again, who knows what happens - your application might crash for a completely different reason. – VLAZ Jan 20 '21 at 19:32

2 Answers2

1

This has nothing to do with promises.

There are some promises doing their asynchronous work (as requesting data from a remote endpoint)

Promises do not do any work. Promises are only a notification mechanism (and a bit more), they do represent an asynchronous result not the work.

So it depends on that work which you're doing, for whose result you got a promise, and how that API (like your network request) handles being suspended by the operating system. Assuming there are no mistakes in the driver code or library that your JS runtime's host objects exposes, they should be getting an error about the cancelled request. Even if the error code was ignored, any reasonably well-defined API for remote access should at some point run into a timeout, and invoke a callback that will then resolve your promise.

If you are talking about the system being suspended between the time a promise was resolved and the time the then handlers get called, yes the handlers got scheduled and the JS runtime is responsible for normal continuation of the program.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

Yes of course you could have Promises that never resolve. here you have a Promise that never resolve.

const promiseThatNeverResolve = new Promise((resolve, reject) => {})

Though, they are implementation errors... in general asynchronous activities have some timeout to take a determination of the resolution or rejection of the promise.

In any case, I think it has some merit to do the test of the scenario you were mentioning and see what is happening and reason about it.

If you execute the code below and put your laptop to sleep for less than 50 seconds and then awake it. You will see that the Promise resolve OK showing "finished OK". Laptop was able to save the current state of the memory before going to sleep and when was awaken to restart with the same state. This means Promise was saved in Pending state and recover in Pending state. Same thing for node event loop, processes and so on.

But even more... it would work if you wait for more than 60 seconds. The laptop awakes with the same state of event loop, stack and so on (that had before going to sleep), like a time machine that freezes the time and resume it as it no time has passed... so resolve function is still scheduled to be executed. And Promise will still be pending. Then, due to the implementation of setTimeout, it will call the resolve function, at least one, no matter how much time would have passed. If the implementation would have decided to throw an exception then Promise will be rejected and you will see the log of the catch().

It is interesting to observe that after awakening the laptop for more than 60 seconds, it took another 10 seconds to show the successful result... Probably while restoring the internal memory state.

const myProm = new Promise((resolve, reject) => {
  setTimeout(resolve, 50000)
})

myProm.then(()=>console.log('finished OK')).catch(()=>console.log('failed'))
Jose Marin
  • 802
  • 1
  • 4
  • 15