Herylee

ES 5-6-7: 从回调函数到Promises到Generators到Async/awit – 中间

Herylee · 2016-11-27翻译 · 1144阅读 原文链接

让我们通过使用请求库实际使用案例。

步骤 1: 回调地狱 - N层深

这就是典型的NodeJS代码的样子。每一个函数会获取一个具有常用的签名的回调函数: function(err, response){ }

步骤 2: Promises - 1层深

Promise库需要典型的回调函数: function(err, response) { } 然后将这些参数分离成then/catch链式回调 .then(function(response) { }).catch(function(err) { })

你可以使用Q或者其他可以用的promise库。我已经在这里使用bluebird。你必须先“promisify“旧式回调库的方法。

说明你如何必须使用“request.getAsync”代替“request.get”。这就称为“promisification” (line #2) - 它将正则方法转换为promise式的方法。而且说明了简化调用foo()的过程。

step 3: Promises+Generators - 0层

让我们结合promises和ES6 generators的力量。

现在“foo”几乎是连续的。我们从callback 类型减少到promises的23行,再到promises + generators的19行。它看起来完全没有嵌套函数的平坦。当然,幕后仍有回调发生,但所见即所得。

请注意,我们称之为“foo”的地方仍然使用promises。我们可以使用generators扁平化,这样它成为一个简单的尝试/捕获。

function* callerFunction() {
  try {
    message = yield foo();
    console.log("success!", message);
  } catch (err) {
    console.log("error!", err);
  }
}
callerFunction = Promise.coroutine(callerFunction);
callerFunction();

和你所在的地方叫“调用函数”也可以是扁平的,等等,等等,直到最顶层的应用程序入口点。对于Web应用程序,该入口点是Web框架。如果Web框架意识到使用generators和promises,你可以基本上使所有的函数作为generator和永远的扁平化。那么你将接近的一些内容像koa

转化测试

在写(Mocha等)测试时Generators非常有用。测试通常有很多回调,但是他们按顺序运行。这是浪费异步性。你可以今天使用Generators编写测试案例,不用担心变换测试框架。

步骤 4: ES7 async/await

ES7 async/await 是在generators的上面运作。Babel已经运行中(尽管它仍然在测试阶段),因此你可以今天尝试。

等等,它是如何工作的?

这整个魔幻简单的运作是由于NodeJS回调函数有一个标准的签名 function(err, response) { }

Promise 库仅仅在你的代码间,目标函数 (request.get/post/…)和延迟对象间担任粘连作用,

deferred = // create a Deferred() object
customCallback = function(err, response) {
  if (err) deferred.reject(err);
  else deferred.resolve(response);
}
// call original request.get/post/... with customCallback
// return you the Deferred's promise

当ES6引入generators,Promise库象征着黑客钩连在一起:如果你“生成一个promise”,你会得到返回的解析值。

`**try {**`
 **response          =   yield request.getAsync(...)**
^^^^^^^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 _to get the response_            _yield a promise_
**}    catch (error) { }**
  ^^^^^^^^^^^^^^^^^^^^^
    _catch the error_

Generators如何工作是一个更大的话题。我建议你阅读davidwalsh.name/es6-generators 或者网上大量的文章。

相关文章