正在读取新的JS运行时的homepage
我看到了以下代码:
import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
我从未见过以下语法(等待中):
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
这种语法是什么?
它是特定于deno的,还是在this tc39提案中找到的顶层等待项?
编辑:为什么可以在async
函数的外部中使用它?
答案 0 :(得分:8)
for await...of
语句用于遍历异步迭代器,而serve
返回一个异步迭代器,其中每次迭代都是一个新的传入请求。
是专用于deno还是在此tc39中找到的顶级等待项 提案?
否,它不是特定于Deno,而是different proposal比top-level await
。
这是asyncIterator
的一个简单示例,该示例也可以在浏览器中使用(非专用)
const obj = {
async *[Symbol.asyncIterator]() {
for(let i = 0; i < 10; i++)
yield new Promise(resolve => setTimeout(() => resolve(i), 100));
}
};
(async() => {
// You don't need the wrapper if the environment
// supports top-level await, e.g: Deno
for await(const i of obj)
console.log(`${i}`, new Date())
})();
编辑:为什么不能在异步功能之外使用它?
因为Deno支持top-level await
答案 1 :(得分:1)
当我决定使用 Deno 时,这也引起了我的注意。我喜欢 Deno,因为它是 ES6 原生的,比如 Promises、Import-Export,而且你甚至不需要像 Node 中的 npm,只需 import
来自 url 的包。
现在这个 async
和 await
抽象可以简化代码,但它也隐藏了很多东西,有些人基本上很难理解到底发生了什么。< /p>
我首先建议您抽出一些时间阅读this beautiful article on asychronous iteration。
事情是,在启动服务器的非常基本的代码中,就像
import { serve } from "https://deno.land/std@0.87.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://127.0.0.1:8000/");
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
由于某种原因,当收到请求时,您必须接受 for await
循环旋转一次。实际上这正是它的作用。驱动异步迭代和承诺的机器是隐藏的。
现在我们应该知道 s
中的;
const s = serve({ port: 8000 });
实际上是一个异步可迭代对象。所以它有一个名为 [Symbol.asyncIterator]
的方法。当您像 s[Symbol.asyncIterator]()
一样调用它时,您将获得一个带有 next
方法的异步迭代器对象。通常,当调用 next()
时,同步迭代器会收到一个像 {value: "stg", done: false}
这样的对象,但在异步迭代器中会收到 Promise
。这个承诺,一旦在收到请求时解决(或在发生错误时拒绝)给我们一个像
{ value: ServerRequest Object
, done : false
}
所以上面的代码也可以写成;
import { serve } from "https://deno.land/std@0.87.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://127.0.0.1:8000/");
var rqs = s[Symbol.asyncIterator](),
srv = (app,rqs) => rqs.next().then(rq => (app(rq.value), srv(app,rqs))),
app = req => req.respond({body: "Hello World\n"});
srv(app,rqs); // receive requests and handle them with your app