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);
});
CodePudding user response:
I would advise reading the follow pages in the Raku docs :
Note that Raku doesn't have a built library for doing web requests but there are a few options.
All of these are make blocking requests but a simple start
will turn the request into a Promise
you can chain off. You may also want to checkout Cro which is a full library for building both client and server side systems that are asynchronous from the ground up.
I hope that's enough to get you started. Good luck.
CodePudding user response:
A Raku Promise
plays 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 Promise
is 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 Promise
using my $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 the Promise
object from an API of some kind, it's usually wise to obtain the vow - the exclusive right to keep or break the Promise
, before returning it.
One can use .then
, noting that it only takes one function and this is passed the Promise
itself, and .result
is used to access the result; trying to access the result of a broken Promise
will rethrow the exception.
As in JavaScript, using await
instead of .then
is generally preferred. Unlike in JavaScript, there's no async
keyword in Raku: you can await
anywhere! 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 the Promise
is kept and the continuation is scheduled. As in .Net, you might end up on a different thread after an await
. You can await
on a non-pool thread (such as the main thread), and then it's a blocking wait on the Promise
.
Since Raku
has had Promise
in the standard library from the first release, asynchronous built-ins are provided entirely in terms of Promise
(and Supply
for streams of asynchronous values). So the setTimeout
equivalent is Promise.interval($seconds)
, for example.
Overall: the rough idea of what a Promise
is in Raku will serve you well, but there's a different API and different idioms to pick up.