Promise is a well-defined built-in object that makes it easy, among other things, to chain synchronous or asynchronous operations.
Task is an object defined in trace_viewer/base that can be used to chain synchronous operations.
Since both tasks and promises allow chaining operations it's easy to confuse them. The goal of this page is to clarify how the classes differ and when to use either.
A first important difference is that tasks cannot be used with asynchronous operations. In a
Promise, you can chain an asynchronous operation by calling
then(functionReturningAPromise). On the other hand, if you create a task from
functionReturningAPromise and call
after() on it, then the subsequent task will execute before the promise is resolved.
Another difference is that it‘s possible to run a task in a synchronous way. Calling
run() on a task will block until the first task in the chain is completed. This is made possible by the fact that all operations in the task queue are synchronous. Compare this to
Promise which doesn’t have a
run method and for which execution is scheduled as soon as the promise is created.
Finally, where tasks allow a queue of dependent operations, promises are more flexible and allow creating a more complex dependency graph between operations via
Chaining operations is similar:
An important difference, though is a task can only have one
after() task. Trying to do
taskA.after(taskB); taskA.after(taskC); will result in a runtime error. Promises have no such limitations.
In addition to
after(), tasks expose the method
subtask() that makes it possible to insert tasks in the execution chain, even as the operations in the chain are being executed. Promises do not directly support this feature.
Tasks have a
run() method to synchronously execute the next operation in the queue. Promises have no such thing, and getting control back once a promise has executed requires the use of
Task.RunWhenIdle is another API call that is not available on promises. It schedule the task queue to be gradually consumed, tying task execution to
requestAnimationFrame in a way that makes sure not to bust the time budget for a frame. Given its asynchronous nature
RunWhenIdle returns a
Note that there are a number of other minor API differences that are omitted here.
If some of the operations you want to chain are asynchronous then you don‘t have a choice and must use
Promise. If you want to chain only synchronous operations, then
Task may be the right choice for you, especially if you plan on executing your operations when the application is idle, in which case you’ll want to benefit from
It‘s sad that the nature of tasks makes it impossible to use
RunWhenIdle with an asynchronous operation. It might be interesting to figure out whether it’s possible to build a
RunWhenIdle on top of promises. Also, if the
subtask() API of tasks make the code simpler in some instances it may be interesting to try to reproduce it on top of promises. Given these improvements to
Promise it may be possible to eventually remove