8.4 Job and Job Queues

Job是一个抽象操作,就是一个当没有其他ECMAScript计算正在进行的时候启动的一个ECMAScript计算。一个JOb抽象操作一般会被定义为可以接受任意个Job参数。

只有当execution context stack 为空并且没有running execution context 时,才可能启动执行Job。一个PendingJob时一个要求在未来执行的Job,它在内部是Record,其字段定义在Table 25 中。一旦Job启动执行,一定会执行完成,在这期间不会有其他的Job启动。然而,当前值执行的Job或者外部的事件可能会加入额外的PendingJobs,他们会在执行完当前的Job后的某个时机启动执行。

表 25 PendingJob Record Fields
字段名 意义
[[Job]] Job抽象操作的名字 这就是当PendingJob启动的时候会执行的抽象操作,Jobs是抽象操作,他们使用NextJob 而不是平常那样,返回一个值,告诉你他们已经完成了。
[[Arguments]] 一个List 一组参数,当[[Job]]被激活的时候,会传个[[Job]]
[[Realm]] 一个Realm Record 用来启动执行上下文,当启动PendingJob的时候
[[ScriptOrModule]] 一个Script Record或者Module Record 用来启动执行上下文,当启动PendingJob的时候
[[HostDefined]] 任意值,默认是undefined 保留的一些宿主环境需要使用的字段,为了给pending Job附加额外信息。

Job队列是一个先进先出的PendingJob的队列,每个Job队列都有一个名字,并且全部可用的Job队列由ECMAScript实现定义。每种实现都至少会有表26中的Job队列。

表 26 必须的Job队列
名字 目的
ScriptJobs 验证并且执行ECMAScript 脚本或者Module源代码的Job,如第10章和第15章
PromiseJobs 响应一个已经settle的Promiser(见25.4章)

一个要在未来执行的Job是靠入列来实现的,在一个Job队列中,一个PendingJob record包含一个Job抽象操作名和必须的参数值。当execution context stack 为空并且没有running execution context 时,ECMAScript实现会从一个Job队列中移除第一个PendingJob,然后使用其中包含的信息来创建一个执行上下文,并且开始执行这个关联的Job抽象操作。

PendingJob在一个单一队列中,总是先进先出的顺序,这个规范并没有定义多个队列之间的服务顺序。一个ECMAScript实现可能会交织着在多个任务队列之间切换。一个ECMAScript实现必须定义当execution context stack 为空并且没有running execution context 时会发生什么。

注意:典型的ECMAScript实现会有预先启动的Job队列,并且最少有一个Job队列,并且其中会有一个Job被第一个执行。一个实现可能会选择在当前Job执行完并且Job队列是空的时候释放所有资源并且终止执行。另一种情况是,它会选择等待特殊定义实现的代理或者机制确保会把一个新的PendingJob入列。

下面抽象操作是用来创建和管理Job和Job队列的:

8.3.1 EnqueueJob (queueName,job,arguments)

这个 抽象操作要求三个参数,queueName,Job,arguments,执行过程如下:

  1. Assert: Type(queueName) is String and its value is the name of a Job Queue recognized by this implementation.
  2. Assert: job is the name of a Job.
  3. Assert: arguments is a List that has the same number of elements as the number of parameters required by job.
  4. Let callerContext be the running execution context.
  5. Let callerRealm be callerContext's Realm.
  6. Let callerScriptOrModule be callerContext's ScriptOrModule.
  7. Let pending be PendingJob{ [[Job]]: job, [[Arguments]]: arguments, [[Realm]]: callerRealm, [[ScriptOrModule]]: callerScriptOrModule, [[HostDefined]]: undefined }.
  8. Perform any implementation or host environment defined processing of pending. This may include modifying the [[HostDefined]] field or any other field of pending.
  9. Add pending at the back of the Job Queue named by queueName.
  10. Return NormalCompletion(empty).

8.3.2 NextJob

如果算法步骤是如下:

  1. NextJob result

使用如下操作替换:

  1. Return result

Job的抽象操作必须包含一个返回操作或者ReturnIfAbrupt,NextJob result操作和如下步骤是一样的:

  1. If result is an abrupt completion, perform HostReportErrors(« result.[[Value]] »).
  2. Suspend the running execution context and remove it from the execution context stack.
  3. Assert: The execution context stack is now empty.
  4. Let nextQueue be a non-empty Job Queue chosen in an implementation defined manner. If all Job Queues are empty, the result is implementation defined.
  5. Let nextPending be the PendingJob record at the front of nextQueue. Remove that record from nextQueue.
  6. Let newContext be a new execution context.
  7. Set newContext's Function to null.
  8. Set newContext's Realm to nextPending.[[Realm]].
  9. Set newContext's ScriptOrModule to nextPending.[[ScriptOrModule]].
  10. Push newContext onto the execution context stack; newContext is now the running execution context.
  11. Perform any implementation or host environment defined job initialization using nextPending.
  12. Perform the abstract operation named by nextPending.[[Job]] using the elements of nextPending.[[Arguments]] as its arguments.

results matching ""

    No results matching ""