当我决定使用 Deno 时,这也引起了我的注意。我喜欢 Deno,因为它在 ES6 上是原生的,比如 Promises、Import - Export,而且你甚至不需要像 Node 中那样的 npm,只需要import
来自 url 的包。
现在,为了简化代码,这个async
和await
抽象是可以的,但它也隐藏了很多东西,有些人基本上很难理解到底发生了什么。
我首先建议您花点时间阅读这篇关于异步迭代的精美文章。
问题是,在启动服务器的非常基本的代码中,
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
中会收到 a 。这个承诺,一旦收到请求时解决(或者如果发生错误则拒绝)给我们一个像
{ 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