当我决定使用 Deno 时,这也引起了我的注意。我喜欢 Deno,因为它在 ES6 上是原生的,比如 Promises、Import - Export,而且你甚至不需要像 Node 中那样的 npm,只需 import 来自 url 的包。
现在这个async 和await 抽象是为了简化代码,但它也隐藏了很多东西,有些人基本上很难理解到底发生了什么。
我首先建议您花点时间阅读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 in;
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