Async & Await
This document is a quick introduction to using the
async
and await
syntactic sugar in CloudCode tasks and in TypeScript apps.async
and await
works in CloudCode tasks (both JS and TS) and TypeScript apps. It does not work in the app logic for JavaScript apps.Start with this interactive introduction to
async
& await
if you are not familiar with the syntax at all.In JourneyApps many operations are asynchronous. We use
async
& await
to handle this.In CloudCode, your main
run
function should always be async
:export async function run() {
// Code here
}
Generally, database operations that query the backend are asynchronous, and needs
await
:export async function run() {
var user = await DB.user.first();
console.log('name:', user.name);
// This doesn't hit the database yet, so does not need `await`
var assignment = DB.assignment.create();
assignment.user(user);
await assignment.save();
}
Fetch calls are also asynchronous and therefore require an
await
:export async function run() {
var response = await fetch("http://api.open-notify.org/iss-now.json");
if(!response.ok) {
throw new Error('Request failed: ' + response.statusText);
}
var body = await response.json();
return body.iss_position;
}
If you define an
async
function, you also need to await
on its response:async function getLocation() {
var response = await fetch("http://api.open-notify.org/iss-now.json");
if(!response.ok) {
throw new Error('Request failed: ' + response.statusText);
}
var body = await response.json();
return body.iss_position;
}
export async function run() {
var location = await getLocation();
return {location: location};
}
Notable
async
operations:someModel.first()
someQuery.toArray()
someQuery.first()
someQuery.destroyAll()
someQuery.count()
someDbObject.save()
someDbObject.destroy()
someDbObject.reload()
Getting
belongs-to
relationships are also async
. If a chain of belongs-to
lookups are performed, each one requires an await
. For readable code, it is recommended to do each belongs-to
lookup on a separate line. For example:// Works, but not readable
let clientName = (await (await user.assignment()).client()).name;
// More readable
let assignment = await user.assignment();
let client = await assignment.client();
let clientName = client.name;
for
loops require specific attention: someArray.forEach
does not wait for async
functions to complete, so it is recommend to use a for...of
loop instead:var objects = await DB.myobject.all().toArray();
for(let object of objects) {
// ...
}
For example:
export async function run() {
// Task to recalculate the totals for all invoices
var invoices = await DB.invoices.all().toArray();
for(let invoice of invoices) {
var line_items = await invoice.line_items.toArray();
var total = 0;
for(let line_item of line_items) {
var product = await line_item.product();
var price = product.price * line_item.quantity;
total += price;
}
invoice.total = total;
await invoice.save();
}
}
Last modified 10mo ago