关注前端小鱼,阅读更多原创技术文章异步编程ES6新增了正式的Promise引用类型,支持更优雅的异步逻辑定义和组织在接下来的几个版本中,使用async和await关键字定义一个异步函数的机制相关代码→同步vs.异步同步行为处理器指令在内存中顺序执行每条指令按照在单线程状态下出现的顺序执行,并立即获取本地存储的信息system(orregistersorsystemmemory)letx=3//操作系统在栈内存上分配一块空间用于存放浮点值x=x+4//对这个值做一次数学计算,并写入计算结果返回到先前分配的内存中。异步行为类似于系统中断。当前进程之外的实体可以触发代码执行,通常是在定时回调中。执行线程不知道什么时候将信息存储到系统本地(或寄存器或系统内存),取决于回调是否适合从消息队列中出列并执行letx2=3//操作系统为在栈内存上存储浮点值setTimeout(()=>{x=x+4//执行线程不知道x的值什么时候会改变,这取决于回调什么时候从消息中出队queueandexecuted},1000)以前的异步编程方法早期JS只支持回调函数表示异步操作,多个异步操作串联操作需要深度嵌套回调函数(回调地狱)functiondouble(value){setTimeout(()=>{setTimeout(()=>{console.log(value*2)},2000)//2000毫秒后,JS运行时会将回调函数推送到消息队列中执行},1000)//1000毫秒后,JSruntime会将回调函数推送到消息队列中执行}double(3)//6(约3000毫秒后),double()函数在setTimeout成功调度异步操作后立即退出异步操作返回值如果setTimeout操作返回有用的值,可以为异步操作提供回调,将值传递到需要的地方functiondouble2(value,callback){setTimeout(()=>{callback(value*2)//1000毫秒后,将回调函数推送到消息队列},1000)}double2(3,(x)=>console.log(`Iwasgiven:${x}`))//'Iwasgiven:6'(大约1000毫秒后)failurehandling回调模型中异步操作的failurehandling(successCallback&failurecallback)这种方法已经不可取了,因为回调必须在异步操作初始化的时候定义,异步函数的返回值只存在很短的时间,以返回值为参数的回调必须是准备接收它functiondouble3(value,success,failure){setTimeout(()=>{//初始化异步操作时必须定义回调try{if(typeofvalue!=='number'){throw'必须提供number作为第一个参数'}success(value*2)}catch(error){failure(error)}},1000)}constsuccessCallback=(x)=>console.log(`Success:${x}`)constfailureCallback=(e)=>console.log(`Failure:${e}`)double3(3,successCallback,failureCallback)//'Success:6'(大约1000毫秒后)double3('3',successCallback,failureCallback)//'Failure:Mustprovidenumberasfirstargument'(afterabout1000milliseconds)嵌套异步回调如果异步返回值依赖于另一个异步返回值,则需要嵌套回调(回调地狱,不可扩展,代码难以维护)functiondouble4(value,success,failure){setTimeout(()=>{try{if(typeofvalue!=='number'){throw'必须先提供数字argument'}success(value*2)}catch(error){failure(error)}},1000)}constsuccessCallback2=(x)=>{double4(x,(y)=>console.log(`Success:${y}`))//异步返回值依赖于另一个异步返回值,嵌套回调创建“回调地狱”}constfailureCallback2=(e)=>console.log(`Failure:${e}`)double4(3,successCallback2,failureCallback2)//'Success:12'(afterabout2000ms)Summary&Questions同步和异步行为在执行线程和内存存储方面有什么区别?写一段代码,把setTimeout的返回值作为回调传给函数,执行这个函数得到结果写一段代码,在回调模型中做异步操作的成功/失败处理,说说关于为什么不再需要这种方法。回调地狱是如何形成的?它的缺点是什么?
