JS异步编程 (2) - Promise、Generator、async/await

JS异步编程 (2) - PromiseGeneratorasync/await

 

上篇文章我们讲了下JS异步编程的相关知识,比如什么是异步,为什么要使用异步编程以及在浏览器中JS如何实现异步的。
最后我们捎带讲了几种JS异步编程模式(回调,事件和发布/订阅模式),这篇我们继续去深入了解下其他的几种异步编程模式。

 

Promise

Promise是ES6推出的一种异步编程的解决方案。其实在ES6之前,很多异步的工具库就已经实现了各种类似的解决方案,而ES6将其写进了语言标准,统一了用法。Promise解决了回调等解决方案嵌套的问题并且使代码更加易读,有种在写同步方法的既视感。

我们先来简单了解下ES6中Promise的用法

var p = new Promise(function async(resolve, reject){ // 这里是你的异步操作 setTimeout(function(){ if(true){ resolve(val); }else{ reject(error); } }, 1000) }) p.then(function(val){ console.log('resolve'); }, function(){ console.log('reject'); })

首先,ES6规定Promise是个构造函数,其接受一个函数作为参数如上面代码中的async函数,此函数有两个参数,resolve、reject分别对应成功失败两种状态,我们可以选择在不同时候执行resolve或者reject去触发下一个动作,执行then方法里的函数。

我们可以简单对比下回调的写法和promise的写法的不同

 

对于传统回调写法来说,一般会写成这样

asyncFn1(function () { asyncFn2(function() { asyncFn3(function() { // xxxxx }); }); });

 

或者我们将各个回调函数拆出来独立来写以减少耦合,像是这样:

function asyncFn1(callback) { return function() { console.log('asyncFn1 run'); setTimeout(function(){ callback(); }, 1000); } } function asyncFn2(callback) { return function(){ console.log('asyncFn2 run'); setTimeout(function(){ callback(); }, 1000); } } function normalFn3() { console.log('normalFn3 run'); } asyncFn1(asyncFn2(normalFn3))()

 

最后我们看下Promise的写法

function asyncFn1() { console.log('asyncFn1 run'); return new Promise(function(resolve, reject) { setTimeout(function(){ resolve(); }, 1000) }) } function asyncFn2() { console.log('asyncFn2 run'); return new Promise(function(resolve, reject) { setTimeout(function(){ resolve(); }, 1000) }) } function normalFn3() { console.log('normalFn3 run'); } asyncFn1().then(asyncFn2).then(normalFn3);

这样来看无论是第一种还是第二种写法,都会让人感到不是很直观,而Promise的写法更加直观和语义化。

 

Generator

Generator函数也是ES6提供的一种特殊的函数,其语法行为与传统函数完全不同。

我们先直观看个Generator实际的用法

function* oneGenerator() { yield 'Learn'; yield 'In'; return 'Pro'; } var g = oneGenerator(); g.next(); // {value: "Learn", done: false} g.next(); // {value: "In", done: false} g.next(); // {value: "Pro", done: true}

Generator函数是一种特殊的函数,他有这么几个特点:

声明时需要在function后面加上*,并且配合函数里面yield关键字来使用。

在执行Generator函数的时候,其会返回一个Iterator遍历器对象,通过其next方法,将Generator函数体内的代码以yield为界分步执行

具体来说当执行Generator函数时,函数并不会执行,而是需要调用Iterator遍历器对象的next方法,这时程序才会执行从头或者上一个yield之后 到 到下一个yield或者return或者函数体尾部之间的代码,并且将yield后面的值,包装成json对象返回。就像上面的例子中的{value: xxx, done: xxx}。

value取的yield或者return后面的值,否则就是undefined,done的值如果碰到return或者执行完成则返回true,否则返回false。

我们知道了简单的Generator函数的用法以后,我们来看下如何使用Generator函数进行异步编程。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssjpy.html