Async Iteration


const http = require('http');
http.createServer(async (req, res) => {
  try {
    let body = '';
    req.setEncoding('utf8');
    for await (const chunk of req) {
      body += chunk;
    }
    res.write(body);
    res.end();
  } catch {
    res.statusCode = 500;
    res.end();
  }
}).listen(1337);

for-await-of语法让人马上想到的就是Generator语法(ES2017)。这种语法和yield return带来的差不多,但是更加具有泛用性(可以少包装一层代码)。同时,语法相当简洁明了。这边可以认为这是一个Node式.on语法的一种语法糖包装。通过这种语法糖,实际编写的时候就不再需要.on('data').on('end')的两次包装了。

个人认为这种思路与C#中的using,Python中的with类似,都是一种对ReadableStream的简化封装。

现在已经可以在生产环境中使用这些新函数了!从 Node.js 8(V8 v6.2 / Chrome 62)开始已经完全支持异步函数,并且从 Node.js 10(V8 v6.8 / Chrome 68)开始已经完全支持异步迭代器和生成器!

Reference: http://2ality.com/2016/10/asynchronous-iteration.html

Misc

Normal (synchronous) generators help with implementing synchronous iterables. Asynchronous generators do the same for asynchronous iterables. For example, we have previously used the function createAsyncIterable(syncIterable) which converts a syncIterable into an asynchronous iterable. This is how you would implement this function via an async generator:

async function* createAsyncIterable(syncIterable) {
    for (const elem of syncIterable) {
        yield elem;
    }
}