浅谈异步请求(xhr 与 fetch)

   这篇文章是5.10日张言学姐的分享会之后的感悟与小结,张言学姐原博为“浅析 XMLHttPRequest API与Fetch API”,原博地址:https://zhangyan123.github.io/2016/11/01/%E6%B5%85%E6%9E%90XHR%E4%B8%8EFetch/

异步

首先谈到异步,异步到底是个什么东西呢?

首先我们到一个表单提交页面看看。下图是一个普通的注册页面。

 

image

在很久之前,只有同步请求的时候,程序必须是按顺序执行的,这样很傻。。。。

为什么呢?假如我要提交上面那种表单,全部输入完了页面不会有任何反应,点击提交之后才会告诉你哪一项有问题,这个时候你要重新填表单。重新。。。。如果表单很长,你可能会砸电脑。

 

为了解决这种状况,js出现了异步。我们填表单,每填完一项。都会检查,错误就会报错。。。。像下面这样。

image

简直不要太良心。。。这就是同步和异步的区别。然后,稍微深入一下。

异步的机制是什么样呢。。。

难道就是多个函数一起执行么。。。

当然不是。。js是一门单线程的语言,这是什么意思。。。这就是说js在一个时间只能处理一个玩意儿。。。。

 

那这样有什么好处,为什么不一次处理多点呢。看下面这张图。

image

如果是单线程,那么任务a和任务b肯定是等另一个执行完了再去执行另一个(想象任务为一个函数)。but多线程的话,就可能任务a执行到一半,这个时候任务a在等待,处理器转而去处理任务b。

这样就避免不了可能会发生资源的抢占,也就是说,b不小心把a的东西破坏掉了。这样a再处理的时候就会发生错误。

 

这样也是有解决办法的。然而js选择了最简单粗暴的一种。。。就是。。。我就只做成单线程。。。。

 

现在再回到异步,那么js如何实现异步呢。如果一个函数的执行时间可能比较长(比如请求数据),js会先把这个函数拿到一边,处理下面的程序,等到处理器空闲了再处理这个函数。就像settimeout一样。

等待一段时间再执行。

 

就像上面的表单。你填表单的时候,处理器是空闲的。就顺便发送一下请求检查一下你的数据是不是符合要求。。。

 

 

XMLHttpRequest

嗯。。。这个玩意太长了不好念,所以一般咱们叫他XHR,嗨呀。这样念就舒服多了。。。

首先我们来解析一下这个单词,就是xml形式的http请求对吧。http请求就不多说了,但是xml是个啥。官方的话就是可拓展标记语言。其实呢,就是纯文本。。。而且要求很严格。。。他把要传输的东西变成纯文本方便你传输。。

 

这个玩意就是为了。。。嗯。。。和后端交互。。上代码吧。。。

var xhr = new XMLHttpRequest(); 

xhr.open('post', '/login');

 xhr.responseType = 'json';
 
xhr.onload = function() { console.log(xhr.response); };
 
xhr.onerror = function() { console.log("Booo"); };
 
xhr.send(data);

这是很简易的写法。。。平时不能这样写。。。

首先咱们新建一个xhr对象。。。为了传输数据。。。那么底下的内容。。。就是他要干的事情。。

首先开始一个请求open()。。。

表示我要开始准备请求,第一个传入值是请求方式,第二个是url地址。第一个值是post代表上传,get的话就代表索取。。。。

然后第三行是咱们说明一个返回值的数据类型。这里是json类型。。。一般也都用这个。。因为方便。。也可以用xml但是因为太严格。。不太好用。。

声明一下json和jsonp完全不是一个类型的东西。。jsonp和ajax也没有关系!!

具体看这http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

然后第四行和第五行就是上传成功或者出错了得到的东西,相当于一个事件监听器。。

 

准备工作基本做完了。剩下的就是把请求发送了。。send一下。data是要发送的数据。。

如果要处理兼容性啊,要处理请求啊,根据不同的状态做出反应啊。。你就要写出这样的代码。。。

var xmlhttp, data=new FormData();
 data.append('mail','15527216125@163.com'); 
data.append('password','123456') 

if (window.XMLHttpRequest)
 { xmlhttp = new XMLHttpRequest(); 
 }else if(window.ActiveXObject)
 { var versions=[ 
 'MSXML2.XMLHTTP.3.0', '
 MSXML2.XMLHTTP', 
 'Microsoft.XMLHTTP' ]; 

for(var i=0;i< versions.length;i++)
{  
  try{
     xmlhttp=new ActiveXobject(versions[i]); 
     break;
     }
   catch(e){}
 } 
} 

xmlhttp.onreadystatechange = function () 
{ 
if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 )

 { console.log(JSON.parse(xmlhttp.responseText);     } 

}; 


xmlhttp.open("post", '/login' , false); //初始化XHR对象,

readystate=1 xmlhttp.send(data); //参数用于传输

data readystate=2 // xmlhttp.abort(); //停止请求,用于多次连续点击处理及时禁止回调

心态崩了对不对。。我也不解释它了。。。然后。。。jqery就来了个$.ajax。

把所有的东西封装了起来。。。

变成了这个样子。。。

jQuery:
$.ajax({
  url: '/login',
  method: 'post',
  data:{mail:'15527216125@163.com',password:'123456'},
  success:function(res){console.log(res)}
  
});

瞬间觉得离不开jqery了对不对!!!

而且,jqery还把jsonp装在了这个东西里面!!可以方便的跨域了!!这就很舒服。。。。

 

但是首先呐,这样咱们就离不开jqery了,仿若被绑架。。其次又有一个问题。。。。回调地狱。。。。

自此开始下一个小标题。。

 

promise与fetch

 

嘛,既然是异步的请求,那么如果有多个他们回来的顺序怎么确定呢。。。

答案是!!随机!!看处理快慢喽。。

突然感觉仿若智障一样。。。假如我要查询一个地方的天气。。。来看下面的伪代码。。。

func1(){    
  //发送请求,获得国家
}

func2(){
//根据国家,发送请求,获得省份
}

func3(){
//根据省份,发送请求,获得天气
}

你说你是随机的。。exo  me?那如果我func1请求是最慢的。。。那剩下的两个函数就报error了嘛?

那只能说。。是的。。。

那么该怎么解决呢。。。这就发生了回调地狱。。。。

(func(){   //纯纯的伪代码
    $.ajax({
      //...
      success:function(){
      //fun1  获得了国家
      $.ajax({
        //...
        success:function(){
               //func2...获得了省份
                  ……………………………………….
                      }    
        }
      });
      }
    })
})();

如果毁掉次数很多。。。。。。。。。。。那眼睛就吓掉了。。。。

这时候出现了promise。。。这个东西的then方法可以解决这个问题。。。。。。。。。。。。。

具体看promise到底是什么东西看这里http://www.cnblogs.com/lvdabao/p/es6-promise-1.html

刚刚好。fetch返回的又是一个promise对象。,好完美。。。。。那么咱们可以这样

fetch(...).then(fun2)
          .then(fun3)//各依赖有序执行

回调地狱看起来就舒服多了。。。

process的功能可不止这些。他是一个很强大的对象。。。解决了很多异步问题。。具体的在上面博客看。。。

所以呀,fetch也就很神奇。。而且我们也可以用原生的js了。。。ps(fetch用起来甚至像jqery一样简单。。。)

 

以上便是整理的浅谈内容。。。

posted @ 2017-05-18 17:19  Taniffer  阅读(7840)  评论(1编辑  收藏  举报