I'm learning asynchronous programming in JS and I couldn't help but noticed both JS and Raku has some construct for asynchronous programming with the same name, however I'm uncertain to what extent the knowledge from one can transfer to the other. I tried reading JS to Raku but the section about async programming is mostly barren.
For example, is it possible to do something like this in Raku?
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
Or something like this if I want to create my own promises?
function getLanguages() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() >= 0.5;
if (success) {
const languages = ['js', 'perl', 'python', 'raku'];
resolve(languages);
}
else {
reject(new Error('No languages'));
}
}, 0);
});
}
getLanguages()
.then((languages) => {
console.log(languages);
})
.catch((error) => {
console.log(error);
});
A Raku
Promiseplays the same role as a JavaScript one: it models an operation that may complete asynchronously, with the completion either being successful or erroneous. The API is, however, different, so as to fit in with the Raku language more generally.In Raku we say that a
Promiseis either kept (successful completion) or broken (erroneous completion), instead of rejected or resolved. I'm not really sure why that wasn't the case in JavaScript; I've literally never told a person that I've resolved my promise to them!One can make a new
Promiseusingmy $p = Promise.new, but it does not take a function. Rather, one calls$p.keep($value)or$p.break($error). These are actually short for$p.vow.keep($value)and$p.vow.break($error), and if returning thePromiseobject from an API of some kind, it's usually wise to obtain the vow - the exclusive right to keep or break thePromise, before returning it.One can use
.then, noting that it only takes one function and this is passed thePromiseitself, and.resultis used to access the result; trying to access the result of a brokenPromisewill rethrow the exception.As in JavaScript, using
awaitinstead of.thenis generally preferred. Unlike in JavaScript, there's noasynckeyword in Raku: you canawaitanywhere! So long as you're on a thread pool thread, the entire callstack is saved away and the thread freed up to work on something else, until such a time that thePromiseis kept and the continuation is scheduled. As in .Net, you might end up on a different thread after anawait. You canawaiton a non-pool thread (such as the main thread), and then it's a blocking wait on thePromise.Since
Rakuhas hadPromisein the standard library from the first release, asynchronous built-ins are provided entirely in terms ofPromise(andSupplyfor streams of asynchronous values). So thesetTimeoutequivalent isPromise.interval($seconds), for example.Overall: the rough idea of what a
Promiseis in Raku will serve you well, but there's a different API and different idioms to pick up.