当前位置: 首页 > Web前端 > HTML

FE.ES-异步编程演进史

时间:2023-04-02 17:38:40 HTML

本文通过实践从古至今各种封装XMLHttpRequest的方式,了解es中异步编程的实现细节和设计模式。回顾XMLHttpRequest原生写法XMLHttpRequest-MDNvarxhr=newXMLHttpRequest()xhr.timeout=2000xhr.open("POST","path/to/api")xhr.onload=function(){console.log(xhr.status,xhr.responseText)}xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8")xhr.send('{"key":"value"}')常用封装方式1.回调函数传递实现函数请求(方法,url,完成){varxhr=newXMLHttpRequest()xhr.open(方法,url)xhr.onload=function(){if(this.status>=200&&this.status<300)完成(null,xhr.response)elsedone(xhr.response)}xhr.onerror=function(){done(xhr.response)}xhr.send()}//---request('GET','path/to/api',function(err,res){if(err){console.error(err)}console.log(res)})implementfunctionrequest(obj){varxhr=newXMLHttpRequest()xhr.open(obj.method,obj.url)xhr.onload=function(){if(this.status>=200&&this.status<300)obj.success(xhr.response)elseobj.fail(xhr.response)}xhr.onerror=function(){obj.fail(xhr.response)}for(letkeyinobj.header){xhr.setRequestHeader(key,obj.header[key])}xhr.send(obj.data)}//---request({url:'path/to/api',data:{},method:"GET",header:{'Content-type':'application/json'},success(res){console.log(res)},fail(err){console.error(err)}})2.Promise使用Promise-MDNPromise本质上是一个绑定到回调的对象,而不是将回调传递给函数传值方法实现functionrequestPromise(method,url){returnnewPromise(function(resolve,reject){varxhr=newXMLHttpRequest()xhr.open(method,url)xhr.onload=function(){if(this.status>=200&&this.status<300)resolve(xhr.response)elsereject({status:this.status,statusText:xhr.statusText})}xhr.onerror=function(){reject({status:this.status,statusText:xhr.statusText})}xhr.send()})}//---requestPromise('GET','path/to/api').then(function(res1){返回makeRequest('GET',res1.url)}).then(function(res2){console.log(res2)}).catch(function(err){console.error(err)});传对象方式实现functionmakeRequest(opts){returnnewPromise(function(resolve,reject){varxhr=newXMLHttpRequest();xhr.open(opts.method,opts.url);xhr.onload=function(){if(this.status>=200&&this.status<300){resolve(xhr.response);}else{reject({status:this.status,statusText:xhr.statusText});}};xhr.onerror=function(){reject({status:this.status,statusText:xhr.statusText});};if(opts.headers){Object.keys(opts.headers).forEach(function(key){xhr.setRequestHeader(key,opts.headers[key]);});}varparams=opts.params;//如果我们得到一个对象,我们将需要进行字符串化//如果我们有一个字符串,这将被跳过。if(params&&typeofparams==='object'){params=Object.keys(params).map(function(key){returnencodeURIComponent(key)+'='+encodeURIComponent(params[key]);})。加入('&');}xhr.send(参数);});}//Headers和params是可选的makeRequest({method:'GET',url:'http://example.com'}).then(function(datums){returnmakeRequest({method:'POST',url:datums.url,params:{分数:9001},headers:{'X-Subliminal-Message':'Upvote-this-answer'}});}).catch(function(err){console.error('啊,有一个错误!',错误。statusText);});3.fetch,Request(基于承诺)fetch-MDNfetch('path/to/api',{credentials:'include'}).then(function(response){if(response.status>=400){thrownewError("来自服务器的错误响应");}returnresponse.json();}).then(function(stories){console.log(stories);});Request-MDNvarmyRequest=newRequest('path/to/api',{method:'GET',headers:{'Content-Type':'application/json'},mode:'cors',cache:'default'})fetch(myRequest)。then(function(response){//...});4.async/await(ES7)asyncfunction-MDNawait-MDNasyncfunctionf1(){varres=awaitrequestPromise('GET','path/to/api');console.log(res)}f1();其他sleep实际(async/await)functionsleep(time){returnnewPromise(function(resolve,reject){setTimeout(resolve,time)})}varstart=asyncfunction(){for(vari=1;i<=10;i++){console.log(`当前正在等待第${i}次..`);等待睡眠(1000);}};start();co+Generator感觉是async/await到来前的一个过渡方案constco=require('co')//letbegin=newDate();co(function*(){letbought=yieldbuySomething();//console.log(buyed,newDate()-begin);letcleaned=yieldclean();//console.log(cleaned,newDate()-begin);letcook_and_wash=yield[cook(),wash()];//console.log(cook_and_wash,newDate()-begin);leteated=yieldeat();//console.log(eated,newDate()-begin);});异步流程控制库RxJS中文文档参考XMLHttpRequest-MDNusingPromise-MDNHowdoIpromisifynativeXHR?-starkoverflow深入理解ES7的async/awaitfetch-MDNRequest-MDNasync函数-MDNawait-MDNRxJS中文文档Promises/A+