javascript promises, the event loop, and the job queue - Stack Overflow

Consider the following code:function foo() {console.log('foo');new Promise(function(resolve,

Consider the following code:

function foo() {
    console.log('foo');

    new Promise(
        function(resolve, reject) {
            setTimeout(function() {
                resolve('RESOLVING');
            }, 5000);
        }
    )
    .then(
        function(value) {
            console.log(value);
        }
    );
}
foo();

I am trying to understand what happens here correctly:

  1. on executing new Promise the "executer function" is run directly and when setTimeout is called, an operation to add a new entry to the "event queue" is scheduled (for 5 seconds later)
  2. because of the call to then an operation to add to a "job queue" a call to the passed function (which logs to the console) is organised to happen after the Promise is resolved
  3. when the setTimeout callback is executed (on some tick of the event loop), the Promise is resolved and based on point 2, the function argument to the then call is added to a "job queue" and subsequently executed.

Notice I say [a "job queue"] because there is something I am not sure about; which "job queue is it?". The way I understand it, a "job queue" is linked to an entry on the "event queue". So would that be the setTimeout entry in above example? Assuming no other events are added to the "event queue" before (and after) setTimeout's callback is added, wouldn't the entry for the main code (the call to foo) have been (usually) gone (run to pletion) by that time and thus there would be no other entry than setTimeout's for the then's "job queue" entry to be linked to?

Consider the following code:

function foo() {
    console.log('foo');

    new Promise(
        function(resolve, reject) {
            setTimeout(function() {
                resolve('RESOLVING');
            }, 5000);
        }
    )
    .then(
        function(value) {
            console.log(value);
        }
    );
}
foo();

I am trying to understand what happens here correctly:

  1. on executing new Promise the "executer function" is run directly and when setTimeout is called, an operation to add a new entry to the "event queue" is scheduled (for 5 seconds later)
  2. because of the call to then an operation to add to a "job queue" a call to the passed function (which logs to the console) is organised to happen after the Promise is resolved
  3. when the setTimeout callback is executed (on some tick of the event loop), the Promise is resolved and based on point 2, the function argument to the then call is added to a "job queue" and subsequently executed.

Notice I say [a "job queue"] because there is something I am not sure about; which "job queue is it?". The way I understand it, a "job queue" is linked to an entry on the "event queue". So would that be the setTimeout entry in above example? Assuming no other events are added to the "event queue" before (and after) setTimeout's callback is added, wouldn't the entry for the main code (the call to foo) have been (usually) gone (run to pletion) by that time and thus there would be no other entry than setTimeout's for the then's "job queue" entry to be linked to?

Share Improve this question edited Apr 14, 2019 at 15:28 3m3sd1 asked Apr 14, 2019 at 15:24 3m3sd13m3sd1 1509 bronze badges 6
  • Are you asking about a particular implementation? Or for a language-lawyer definition from some standard? – Ivan Rubinson Commented Apr 14, 2019 at 15:27
  • @IvanRubinson A browser like Chrome – 3m3sd1 Commented Apr 14, 2019 at 15:29
  • So Googles V8 engine. – Ivan Rubinson Commented Apr 14, 2019 at 15:30
  • @IvanRubinson would there be that much difference in implementation between different browsers/engines? Is the behaviour not expected to be the same across the board for described scenario? – 3m3sd1 Commented Apr 14, 2019 at 15:32
  • 1 @jonathan no, promises always resolve asynchronously – Jonas Wilms Commented Apr 14, 2019 at 16:39
 |  Show 1 more ment

1 Answer 1

Reset to default 7
  1. on executing new Promise the "executer function" is run directly and when setTimeout is called, an operation to add a new entry to the "event queue" is scheduled (for 5 seconds later)

Yes. More specifically, calling setTimeout schedules a timer with the browser's timer mechanism; roughly five seconds later, the timer mechanism adds a job to the main job queue that will call your callback.

  1. because of the call to then an operation to add to a "job queue" a call to the passed function (which logs to the console) is organised to happen after the Promise is resolved

Right. then (with a single argument) adds a fulfillment handler to the promise (and creates another promise that it returns). When the promise resolves, a job to call the handler is added to the job queue (but it's a different job queue).

  1. when the setTimeout callback is executed (on some tick of the event loop), the Promise is resolved and based on point 2, the function argument to the then call is added to a "job queue" and subsequently executed.

Yes, but it's not the same job queue. :-)

The main job queue is where things like event handlers and timer callbacks and such go. The primary event loop picks up a job from the queue, runs it to pletion, and then picks up the next job, etc., idling if there are no jobs to run.

Once a job has been run to pletion, another loop gets run, which is responsible for running any pending promise jobs that were scheduled during that main job.

In the JavaScript spec, the main job queue is called ScriptJobs, and the promise callback job queue is PromiseJobs. At the end of a ScriptJob, all PromiseJobs that have been queued are executed, before the next ScriptJob. (In the HTML spec, their names are "task" [or "macrotask"] and "microtask".)

And yes, this does mean that if Job A and Job B are both queued, and then Job A gets picked up and schedules a promise callback, that promise callback is run before Job B is run, even though Job B was queued (in the main queue) first.

Notice I say [a "job queue"] because there is something I am not sure about; which "job queue is it?"

Hopefully I covered that above. Basically:

  • Initial script execution, event handlers, timers, and requestAnimationFrame callbacks are queued to the ScriptJobs queue (the main one); they're "macrotasks" (or simply "tasks").
  • Promise callbacks are queued to the PromiseJobs queue, which is processed until empty at the end of a task. Thatis, promise callbacks are "microtasks."

The way I understand it, a "job queue" is linked to an entry on the "event queue".

Those are just different names for the same thing. The JavaScript spec uses the terms "job" and "job queue." The HTML spec uses "tasks" and "task queue" and "event loop". The event loop is what picks up jobs from the ScriptJobs queue.

So would that be the setTimeout entry in above example?

When the timer fires, the job is scheduled in the ScriptJobs queue.

Assuming no other events are added to the "event queue" before (and after) setTimeout's callback is added, wouldn't the entry for the main code (the call to foo) have been (usually) gone (run to pletion) by that time and thus there would be no other entry than setTimeout's for the then's "job queue" entry to be linked to?

Basically yes. Let's run it down:

  • The browser loads the script and adds a job to ScriptJobs to run the script's top-level code.
  • The event loop picks up that job and runs it:
    • That code defines foo and calls it.
    • Within foo, you do the console.log and then create a promise.
    • The promise executor schedules a timer callback: that adds a timer to the browser's timer list. It doesn't queue a job yet.
    • then adds a fulfillment handler to the promise.
    • That job ends.
  • Roughly five seconds later, the browser adds a job to ScriptJobs to call your timer callback.
  • The event loop picks up that job and runs it:
    • The callback resolves the promise, which adds a promise fulfillment handler call to the PromiseJobs queue.
    • That job ends, but with entries in PromiseJobs, so the JavaScript engine loops through those in order:
      • It picks up the fulfillment handler callback job and runs it; that fulfillment handler does console.log
    • That job is pletely done now.

More to explore:

  • Jobs and Job Queues in the JavaScript specification
  • Event Loops in the HTML5 specification

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745464730a4628866.html

相关推荐

  • javascript promises, the event loop, and the job queue - Stack Overflow

    Consider the following code:function foo() {console.log('foo');new Promise(function(resolve,

    8小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信