JavaScriptasynchronous编程:承诺vs生成器

Promise和生成器允许您编写asynchronous代码。 我不明白为什么这两种机制都是在ECMA脚本6中引入的。什么时候最好使用promise,什么时候使用generator?

这两种技术之间没有任何对立。 它们并存在一起,很好地互补。 承诺使您能够获得尚不可用的asynchronous操作的结果。 它解决了厄运问题的金字塔 。 所以,而不是:

function ourImportantFunction(callback) { //... some code 1 task1(function(val1) { //... some code 2 task2(val1, function(val2) { //... some code 3 task3(val2, callback); }); }); } 

你可以写:

 function ourImportantFunction() { return Promise.resolve() .then(function() { //... some code 1 return task1(val3) }) .then(function(val2) { //... some code 2 return task2(val2) }) .then(function(val2) { //... some code 3 return task3(val2); }); } ourImportantFunction().then(callback); 

但即使有了承诺,您也必须以asynchronous的方式编写代码 – 您必须始终将callback函数传递给函数。 编写asynchronous代码比同步更困难。 即使在代码巨大的情况下,我们也很难看到这个algorithm(这是非常主观的,有人可以争论,但是对于大多数程序员来说,我认为这是真的)。 所以我们想以同步方式编写asynchronous代码。 这就是发电机来帮助我们的地方。 所以,而不是上面的代码,你可以写:

 var ourImportantFunction = spawn(function*() { //... some code 1 var val1 = yield task1(); //... some code 2 var val2 = yield task2(val1); //... some code 3 var val3 = yield task3(val2); return val3; }); ourImportantFunction().then(callback); 

哪里最简单的spawn实现可能是这样的:

 function spawn(generator) { return function() { var iter = generator.apply(this, arguments); return Promise.resolve().then(function onValue(lastValue){ var result = iter.next(lastValue); var done = result.done; var value = result.value; if (done) return value; // generator done, resolve promise return Promise.resolve(value).then(onValue, iter.throw.bind(iter)); // repeat }); }; } 

正如你所看到的value (一些asynchronous函数的结果task{N} )必须是一个承诺。 你不能用callback来做到这一点。

还有什么要做的是将spawn技术实施到语言本身。 所以我们用asyncreplacespawnyieldawait ,并来ES7asynchronous/等待 :

 var ourImportantFunction = async function() { //... some code 1 var val1 = await task1(); //... some code 2 var val2 = await task2(val1); //... some code 3 var val3 = await task3(val2); return val3; } 

我build议你观看这个video来更多地了解这个和其他一些未来技术。 如果这个家伙说得太快,放慢播放速度(右下angular的“设置”,或者只按[ shift + < ])

什么是最好的:只是callback,承诺或承诺发电机 – 这是非常主观的问题。 callback是目前可能的最快解决scheme(原生承诺的性能现在非常糟糕)。 使用生成器的承诺为您提供了以同步方式编写asynchronous代码的机会。 但现在他们慢得多,然后简单的callback。

承诺和生成器是不同的软件模式(构造):

  1. http://en.wikipedia.org/wiki/Futures_and_promises
  2. http://en.wikipedia.org/wiki/Generator_(computer_programming);

实际上,发生器不是asynchronous的。

当您需要一次获取一系列值时,发电机很有用,但是每个需求一个。 发生器将在每个调用中立即(同步)返回下一个值,直到到达序列的末尾(或者在无限序列的情况下为无穷大)。

当您需要“推迟”价值时,承诺是有用的,这些价值可能不被计算(或可能不可用)。 当这个值是可用的 – 这是整个值(不是它的一部分),即使它是一个数组或其他复杂的值。

你可以在维基百科文章中看到更多的细节和例子。