Home > Software engineering >  How much does Raku's Promise construct share in common with JavaScript's Promises?
How much does Raku's Promise construct share in common with JavaScript's Promises?

Time:11-18

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.

  • Related