异步编程
一、什么是异步
简单来说,就是任务A完成了一半,暂停不做了,再做任务B,接着再继续任务A剩下的工作。
二、异步的好处是什么
就是不浪费时间,高效。把之前等待资源的时间都充分利用起来干活了
三、实现方法
1、es6之前,大概有四种:回调函数、监听事件、发布/订阅、Promise 对象
2、es6,可以用Gererator函数
四、各方法的优缺点
1、回调函数
缺点:出现多个回调函数嵌套,横下发展,强耦合,难维护
<section id="demo">demo</section> <script type="text/javascript" src="js/jquery-2.1.1.min.js"></script> <script type="text/javascript"> $(() => { $("#demo").animate({ fontSize: '10em' },1000,() => { //回调函数 1 console.log('动画1完成'); $("#demo").animate({ fontSize: '1em' },1000,() => { //回调函数 2 console.log('动画2完成'); $("#demo").animate({ fontSize: '10em' },1000,() => { //回调函数 3 console.log('动画3完成'); }) }); }) }); </script>
2.Promise函数
优点:解决上面的多重嵌套而提出的一种新的写法,把回调函数的嵌套改成了链式调用(then函数连接)
缺点:代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆then
,原来的语义变得很不清楚。
<section id="demo">demo</section> <script type="text/javascript" src="js/jquery-2.1.1.min.js"></script> <script type="text/javascript"> function animate(jq,fontSize){ return new Promise((resolve, reject) => { jq.animate({ fontSize: fontSize}, 1000, function() { /* stuff to do after animation is complete */ resolve(); }); }); } animate($("#demo"),'10em').then( () => { console.log('动画1完成'); return animate($("#demo"),'1em'); }).then( () => { console.log('动画2完成'); return animate($("#demo"),'10em'); }).then( () => { console.log('动画3完成'); }); </script>
3.Generator函数
优点:写法非常像同步操作;有数据交换和错误处理机制
缺点:流程管理不方便(何时执行第一阶段、何时执行第二阶段)
解决方法:(1)结合回调函数: 包装成Thunk函数完成自动执行 (2)结合Promise函数 (例如co模块)
<section id="demo">demo</section> <script type="text/javascript" src="js/jquery-2.1.1.min.js"></script> <script type="text/javascript"> function animate(jq,fontSize){ return new Promise((resolve, reject) => { jq.animate({ fontSize: fontSize+"em"}, 1000, function() { /* stuff to do after animation is complete */ resolve(fontSize); }); }); } const g = function* (){ let a1 = yield animate($("#demo"),'10'); console.log('动画1完成'); let a2 = yield animate($("#demo"),parseInt(a1)-9); console.log('动画2完成'); let a3 = yield animate($("#demo"),parseInt(a2)+9); console.log('动画3完成'); } //自动执行器 function run(generator){ const g = generator(); function next(data){ const result = g.next(data); if(result.done) return result.value; result.value.then(function(data){ next(data); }); } next(); } run(g); </script>