异步编程的解决方案

Posted 前端精髓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步编程的解决方案相关的知识,希望对你有一定的参考价值。


首先先明白一点,异步编程的目标就是怎样让它更像同步编程。


异步编程的解决方案有哪些?


1、回调

2、事件发布订阅

3、Promise

4、Generator

5、async/await

回调

由于node涉及大量的异步操作,所以回调非常常见。


fs.readFile('某个文件', function (err, data) { if (err) throw err; console.log(data);});


回调的问题,第一个就是异常处理,无法再使用try-catch捕获错误,Node在处理异常有一个约定,将异常作为回调的第一个实参传回,如果为空表示没有出错。


异步多级依赖的情况下嵌套非常深,代码难以阅读的维护,也就是我们常说的回调地狱的问题。


发布订阅

订阅事件实现了一个事件与多个回调函数的关联(一对多),是多个异步之间的协作方案。


回调函数可以任意的添加和删除,也可以隔离业务逻辑,保持业务逻辑单元的职责单一。


const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();myEmitter.on('event', () => { console.log('an event occurred!');});myEmitter.on('event', () => { console.log('an event occurred!');});myEmitter.emit('event');


使用事件的方式时,执行流程需要被预先设定,这是有发布订阅模式机制所决定的,Promise 可以先执行异步调用,延迟传递处理的方法。

Promise

Promise是高级接口,发布订阅模式是低级接口。低级接口可以构成更多更复杂的场景,高级接口一旦定义,不太容易变化,不再有低级接口的灵活性,但对于解决典型问题非常有效。


fetch(url, options).then(function(response) {  console.log(res);}, function(error) { console.log(e.code) // ENOTFOUND})

生成器Generators

co 是 TJ 大神基于 ES6 generator 的异步解决方案。要理解 co 你得先理解 ES6 generator,这里就不赘述了。co 最大的好处就是能让你把异步的代码流程用同步的方式写出来,并且可以用 try/catch:


co(function *(){ try { var res = yield fetch(url, options); console.log(res); } catch(e) { console.log(e.code) // ENOTFOUND }})()


但用 co 的一个代价是 yield 后面的函数必须返回一个 Thunk 或者一个 Promise,对于现有的 API 也得进行一定程度的二次封装。

async/await

async function showStuff () { var data = await loadData() // loadData 返回一个 Promise console.log(data) // data 已经加载完毕}
async function todo () { await showStuff() // async 函数默认返回一个 Promise, 所以可以 await 另一个 async 函数 // 这里 showStuff 已经执行完毕}


一比较就会发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。


Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。


可以看到,和用 co 写出来的代码很像,但语意上更清晰。因为本质上 ES7 async/await 就是基于 Promise + generator 的一套语法糖。



总结:解决问题的方式有很多种,我们还是需要具体问题具体分析,根据不同的场景使用最佳的编码方式才是最好的选择。




以上是关于异步编程的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

异步任务类完成后如何更改文本视图的值(在片段中)?

异步编程的终极解决方案 async/await:用同步的方式去写异步代码

Nodejs异步编程

Nodejs异步编程

异步编程的终极解决方案 async/await:用同步的方式去写异步代码

JavaScript学习--Item27 异步编程异常解决方案