本博客未上传githubgithub主页(star+watch,一手动态直接获取):https://github.com/HCThink/h-blog掘金链接,掘金专栏segmentfault主页原创禁止未经授权转载异步处理解决方案系列-1.回调简介异步/异步操作已经是前端领域的一个常见话题。也是前端开发中经常面临的问题。但是,异步问题往往比较复杂,难以处理,尤其是异步问题,往往不是单独出现的,往往有多种组合关系。在实际加工中比较复杂,处理起来比较困难。特别是在频繁的io操作中,或者在节点服务器中,经常会遇到非常复杂的组合异步问题。举一个业务开发中常见的例子:eg:省市县三级级联问题这个问题很常见。假设数据量很大,我们大多数情况下不会一次加载所有的数据,然后做前端级联的方案。取而代之的是,当下拉发生变化时,使用三个数据接口动态请求。这就形成了一个很常见的多异步串行模型。如何处理这样的问题,如何更好地维护多个异步如何在正常执行的同时,让代码在逻辑和结构上更具可读性?我整理一下callbackcpsthunkdefer/promise(non-es6)promise(ES6)generator->co.async/await的处理方式。添加事件监听、订阅和发布模式两种模式列出一系列博客来讨论这个问题。了解我们如何在不同阶段使用不同技术处理同一问题。横向比较不同的解决方案,深入了解技术变化及其背后处理思路和逻辑的变化。回调什么是回调?问这个问题似乎有点多余。每个写过javascript的开发者都会或多或少接触到回调。使用回调的成本非常低。回调函数就像传递一个通用的参数变量一样简单。由于函数式编程的出色支持,使用这项技术基本上没有障碍。我们可以很容易地写一个回调Ajax.get('http://xxxx',{},(resp)=>{//.....})但是,很难回答回调的定义。我们不妨从一些方面来看待回调。回调是一种处理特定问题的模式,是函数式编程诞生的。函数式编程中最重要的技术之一是回调函数。当一个函数作为主调用函数的参数时,往往会在特定的时间和场景(上下文)中被调用,在执行过程中,回调函数选择性地接收函数内部的数据,或者状态(内存),并在处理后有选择地返回,或改变状态(hock)。回调业务模型说了这么多,我们不妨从代码的角度来看解决一个串行异步模型。为了说明问题,我们把问题简化为ABC三个异步(可能是io,网络请求,或者其他。为了描述方便,我们用settimeout来模拟),这三个异步耗时不是,但是他们返回结果必须按照ABC的顺序处理。处理这个问题,我们基本有两种思路:控制异步发送的顺序,在a返回后发送b请求,这样问题就序列化了(在省、市、县模型中,往往需要返回省的返回值来请求省对应的市)。同时发出异步请求,控制处理顺序。方案一:序列化请求//模拟ajax函数functionajax(url){returnfunction(cb){setTimeout(function(){cb({url});},Math.random()*3000);}}//初始化三个请求constA=ajax('/ofo/a');constB=ajax('/ofo/b');constC=ajax('/ofo/c');//控制请求顺序log('ajaxAsend...');A(function(a){log('ajaxAreceive...');log('ajaxBsend...');B(function(b){log('ajaxBreceive...');log('ajaxCsend...');C(function(C){log('ajaxCreceive...');});})})代码很简单,大部分解决方案都是这样,因为返回值A的可以作为B的参数。但是这种模式对应的总时间必须大于三个请求的总和。输出结果如下:ajaxAsend...ajaxAreceive...ajaxBsend...ajaxBreceive...ajaxCsend...ajaxCreceive...方案二:自由请求,序列化处理是一种相对不常见的解决方案,但它非常适合处理没有直接数据依赖的串行请求。//发送容器constsender=[];//稍作修改functionajax(url,time){returnfunction(cb){//记录发送顺序,必须有序sender.push(url);设置超时(功能(){constdata={from:url,reso:'ok'};//传递数据,回调到一个处理函数dealReceive({url,cb,data});},时间);}}//处理顺序返回Result//返回结果容器constreceiver={};functiondealReceive({url,cb,data}){//记录返回结果。可以是无序的receiver[url]={cb,data};for(vari=0;i
