简体   繁体   English

JavaScript异步编程:Promise vs生成器

[英]JavaScript asynchronous programming: promises vs generators

Promises and generators allow you to write asynchronous code. 承诺和生成器允许您编写异步代码。 I do not understand why both of these mechanisms are introduced in ECMA script 6. When is it best to use the promises, and when the generators? 我不明白为什么在ECMA脚本6中同时引入了这两种机制。什么时候最好使用Promise?什么时候使用生成器?

There is no opposition between these two techniques. 这两种技术之间没有对立。 They coexist together complementing each other nicely. 它们共存并很好地互补。 Promises give you capability to get result of an asynchronous operation which does not available yet. 承诺使您能够获得尚不可用的异步操作的结果。 It solves Pyramid of Doom problem. 它解决了厄运金字塔问题。 So instead of: 所以代替:

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

you can write: 你可以写:

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);

But even with promises you must write code in asynchronous fashion - you must always pass callbacks to the functions. 但是即使有承诺,您也必须以异步方式编写代码-您必须始终将回调传递给函数。 Writing asynchronous code is much harder then synchronous. 编写异步代码比同步代码难得多。 Even with promises when the code is huge it becomes difficult to see the algorithm (well, it's very subjective, someone can argue with it. But for majority of programmers I think it's true). 即使有承诺,当代码很大时,也很难看清算法(嗯,这是非常主观的,有人可以与它争论。但是对于大多数程序员来说,我认为这是事实)。 So we want to write asynchronous code in synchronous fashion. 因此,我们想以同步方式编写异步代码。 That's where generators are coming to help us. 那就是发电机来帮助我们的地方。 So instead of code above you can write: 因此,您可以编写上面的代码,而不是上面的代码:

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);

where simplest possible spawn realization can be something like: 最简单的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
    });
  };
}

As you can see value (result of some asynchronous function task{N} ) must be a promise. 如您所见, value (某些异步函数task{N} )必须是一个承诺。 You can't do this with callbacks. 您不能通过回调来做到这一点。

What remains to do is to implement spawn technique into language itself. 剩下要做的是在语言本身中实现spawn技术。 So we are replacing spawn with async and yield with await and are coming to ES7 async/await : 因此,我们用async替换了spawn ,并用await替换了yield ,并开始使用ES7 async / await

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;
}

I recommend you to watch this video to more understand this and some other coming techniques. 我建议您观看此视频,以更全面地了解此技术和其他一些即将来临的技术。 If the guy speaks too fast for you, slow down the speed of playing ("settings" in right bottom corner, or just push [ shift + < ]) 如果该家伙对您说得太快,请放慢演奏速度(右下角的“设置”,或按[ shift + < ])

What is the best: just callbacks, or promises, or promises with generators - this is very subjective question. 最好的是什么:仅仅是回调,promise或使用生成器的promise-这是一个非常主观的问题。 Callbacks is the fastest solution possible at this time (performance of native promises are very bad now). 回调是目前可能的最快解决方案(现在,本机承诺的履行非常糟糕)。 Promises with generators give you opportunity to write asynchronous code in synchronous fashion. 生成器的承诺使您有机会以同步方式编写异步代码。 But for now they much slower then simple callbacks. 但是现在,它们比简单的回调要慢得多。

Promises and Generators are different software patterns (constructs): Promise和Generators是不同的软件模式(构造):

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

In fact, generators aren't asynchronous. 实际上,生成器不是异步的。

Generators are useful when you need to get a series of values not at once, but one per demand. 当您需要一次获取一系列值而不是每个需求一个值时,生成器很有用。 Generator will return next value immediately (synchronously) on every call until it reaches the end of the sequence (or endless in case of infinite series). 生成器将在每次调用时立即(同步)返回下一个值,直到到达序列的末尾(如果是无限序列,则返回无穷)。

Promises are useful when you need to "defer" the value, that may not be computed (or may not be available) yet. 当您需要“推迟”可能尚未计算(或可能不可用)的值时,承诺很有用。 When the value is available - it's the whole value (not part of it) even it is an array or other complex value. 当值可用时-即使是数组或其他复杂值,它也是整个值(而不是其中的一部分)。

You can see more details and examples in wikipedia articles. 您可以在Wikipedia文章中查看更多详细信息和示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM