The async version is simply not blocking the calling thread until the result of the task enqueuing RPC is available. This allows performing other operations before eventually blocking waiting for the RPC result, for example enqueueing multiple tasks in parallel, if needed, or performing
ndb async calls.
It should be noted that you do need to supply an RPC object as the optional
rpc= argument for the async call, it can't be
None - it will be used later on to retrieve the result of the RPC.
From Adding tasks asynchronously:
By default, the Task Queue API calls are synchronous. For most
scenarios, synchronous calls work fine. For instance, adding a task is
usually a fast operation: the median time to add a task is 5 ms and 1
out of every 1000 tasks can take up to 300 ms. Periodic incidents,
such as back-end upgrades, can cause spikes to 1 out of every 1000
tasks taking up to 1 second.
If you are building an application that needs low latency, the Task
Queue API provides asynchronous calls that minimize latency.
Consider the case where you need to add 10 tasks to 10 different
queues (thus you cannot batch them). In the worst case, calling
queue.add() 10 times in a loop could block up to 10 seconds,
although it's very rare. Using the asynchronous interface to add tasks
to their respective queues in parallel, you can reduce the worst-case
latency to 1 second.
If you want to make asynchronous calls to a task queue, use the
asynchronous methods provided by the Queue class and an RPC
get_result() on the returned
RPC object to force the
request to complete. When asynchronously adding tasks in a
transaction, you should call
get_result() on the
RPC object before
committing the transaction to ensure that the request has finished.