【问题标题】:How much does Raku's Promise construct share in common with JavaScript's Promises?Raku 的 Promise 构造与 JavaScript 的 Promise 有多少共同点?
【发布时间】:2022-11-18 01:09:58
【问题描述】:
我正在学习 JS 中的异步编程,我忍不住注意到 JS 和 Raku 都有一些同名的异步编程结构,但是我不确定一个人的知识可以在多大程度上转移到另一个人。我尝试阅读JS to Raku,但有关async programming 的部分大多是空洞的。
例如,在 Raku 中是否可以做这样的事情?
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
如果我想创建自己的承诺,或者类似的东西?
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);
});
【问题讨论】:
标签:
javascript
asynchronous
promise
raku
rakudo
【解决方案1】:
我建议阅读 Raku 文档中的以下页面:
请注意,Raku 没有用于执行 Web 请求的内置库,但有几个选项。
所有这些都是阻塞请求,但是一个简单的start 会将请求变成一个Promise,您可以将其链接起来。您可能还想签出Cro,这是一个完整的库,用于从头开始构建异步的客户端和服务器端系统。
我希望这足以让你开始。祝你好运。
【解决方案2】:
Raku Promise 扮演与 JavaScript 相同的角色:它模拟一个可以异步完成的操作,完成要么成功要么错误。但是,API 有所不同,以便更普遍地适应 Raku 语言。
在 Raku 中,我们说 Promise 要么被保留(成功完成)要么被破坏(错误完成),而不是被拒绝或被解决。我不确定为什么在 JavaScript 中不是这样;我真的从来没有告诉过任何人我已经兑现了对他们的承诺!
可以使用 my $p = Promise.new 创建一个新的 Promise,但它不需要函数。相反,一个调用 $p.keep($value) 或 $p.break($error)。这些实际上是 $p.vow.keep($value) 和 $p.vow.break($error) 的缩写,如果从某种 API 返回 Promise 对象,通常明智的做法是在返回之前先 obtain the vow - the exclusive right to keep or break the Promise。
可以使用.then,注意它只需要一个函数,这个函数传递给Promise本身,.result用于访问结果;尝试访问损坏的 Promise 的结果将重新抛出异常。
与在 JavaScript 中一样,通常首选使用 await 而不是 .then。与 JavaScript 不同,Raku 中没有 async 关键字:您可以在任何地方使用 await!只要您在线程池线程上,整个调用堆栈就会被保存下来,线程就会腾出时间来处理其他事情,直到 Promise 被保留并安排继续。与在 .Net 中一样,您可能会在 await 之后进入不同的线程。可以在非池线程(比如主线程)上await,然后在Promise上是阻塞等待。
由于 Raku 从第一个版本开始在标准库中就有 Promise,因此异步内置函数完全根据 Promise(和 Supply 用于异步值流)提供。例如,setTimeout 等价于 Promise.interval($seconds)。
总的来说:Raku 中 Promise 的粗略概念对您很有用,但是有不同的 API 和不同的习语可供选择。