Deno 顶级等待
Deno top level await
正在阅读 deno 的 homepage 新的 JS 运行时
我看到了下面的代码:
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):
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
这种语法是什么?
它是特定于 deno 还是在 this tc39 提案中发现的顶级等待?
编辑:为什么它可以在async
函数的外部使用?
for await...of
语句用于遍历异步迭代器,serve
returns 异步迭代器,其中每次迭代都会是一个新的传入请求。
Is it specific to deno or is it a top-level-await found in this tc39
proposal?
不,它不是 Deno 特有的,它 different proposal 比 top-level await
。
这是一个简单的例子 asyncIterator
也适用于浏览器(非 deno 独占)
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())
})();
Edit: Why can it be used outside of an async function?
因为 Deno 支持 top-level await
当我决定使用 Deno 时,这也引起了我的注意。我喜欢 Deno,因为它像 Promises、Import - Export 一样原生于 ES6,而且你甚至不需要像 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
在;
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
正在阅读 deno 的 homepage 新的 JS 运行时
我看到了下面的代码:
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):
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
这种语法是什么?
它是特定于 deno 还是在 this tc39 提案中发现的顶级等待?
编辑:为什么它可以在async
函数的外部使用?
for await...of
语句用于遍历异步迭代器,serve
returns 异步迭代器,其中每次迭代都会是一个新的传入请求。
Is it specific to deno or is it a top-level-await found in this tc39 proposal?
不,它不是 Deno 特有的,它 different proposal 比 top-level await
。
这是一个简单的例子 asyncIterator
也适用于浏览器(非 deno 独占)
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())
})();
Edit: Why can it be used outside of an async function?
因为 Deno 支持 top-level await
当我决定使用 Deno 时,这也引起了我的注意。我喜欢 Deno,因为它像 Promises、Import - Export 一样原生于 ES6,而且你甚至不需要像 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
在;
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