JavaScript and TypeScript support various
Callbacks
window.setTimeout(function () {
}, 1000);
$.ajax('/api/user' + id, {
method: 'GET',
success: function(user: IUser) {
},
error: function(reason: any) {
}
});
function getUser(id, success: (user: IUser) => void, error: (reason: any) => void)
$.ajax('/api/user' + id, {
method: 'GET',
success:success,
error: error
});
}
function editUserPhone(id: string, phoneNumber: string, success: (result: boolean) => void, error: (reason: any) => void) {
getUser(id, function (user) {
if (user && user.id) {
getPhone(user.id, function (phone) {
if (phone && phone.id) {
phone.phoneNumber = phoneNumber;
updatePhone(phone.id, phone, function (result: boolean) {
if (result) {
success(result);
} else {
error('Unable to update phone');
}
}, function (reason: any) {
error(reason);
});
} else {
error('No phone found');
}
},
function (reason: any) {
error(reason);
});
} else {
error('No user found');
}
}, function (reason: any) {
error(reason);
});
}
Promises
Let's take a look at the Promise style code. Here, each asynchronous function returns a Promise
object, instead of taking in callback parameters. This Promise provides access to the result of exactly one execution of the nested function. Callbacks that execute many times, such as window.setInterval
, Array.prototype.forEach
, Array.prototype.map
, etc., are used different from Promises.
function editUserPhone(id: string, phoneNumber: string) {
return getUser(id).then(function (user) {
if (!user || !user.id) {
throw 'No user found';
}
return getPhone(user.id).then(function (phone) {
if (!phone || !phone.id) {
throw 'No phone found';
}
phone.phoneNumber = phoneNumber;
return updatePhone(phone.id, phone).then(function (result: boolean) {
if (!result) {
throw 'Unable to update phone';
}
return result;
});
});
});
}
Async/Await
Let's now take a look at the async
and await
symbols. If we mark a function as async
, it implicitly returns a Promise
object. This return type can be autogenerated by TypeScript, so a function that returns a boolean
is now Promise<boolean>
.
Once we have marked it as async
, we gain access to the await
symbol. We simply use await
before executing any function that returns a Promise
. Instead of having to write .then(function (result) { })
, the result will be turned to the left of the statement. We can now write let result = await getValue();
, and result
will be populated with the data return from the asynchronous call.
async function editUserPhone(id: string, phoneNumber: string) {
let user = await getUser(id);
if (!user || !user.id) {
throw 'No user found';
}
let phone = await getPhone(user.id);
if (!phone || !phone.id) {
throw 'No phone found';
}
phone.phoneNumber = phoneNumber;
let result = await updatePhone(phone.id, phone);
if (!result) {
throw 'Unable to update phone';
}
return result;
}