• Ajax同步导致浏览器出现假死现象


    在前端点击按钮,向后端请求数据,在后端计算的过程中,前端会有一个响应界面,我们一般会用一个“正在加载...”的效果。

    在Ajax中,有两种请求方式,即异步和同步,默认是异步请求。

    在异步请求的时候,向后端请求数据,和当前js页面后面的程序执行是异步的。

    而同步执行的时候,后面的js程序,要等到后端数据返回之后,才能继续执行下去。

    如果采用同步执行的方式,会导致动态小效果的加载,看不到“正在加载...”的效果。

    所以可以采用异步的方式代替。

    主要采用jQuery中的Deferred对象,以及其中的一些方法。

    详细的原理可以参见:https://javascript.ruanyifeng.com/jquery/deferred.html或者https://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html(阮一峰  )

    这里摘抄一些原理性的东西,方便记忆:

    1. deferred对象代表了将要完成的某种操作(“延迟”的意思),并提供了一些方法。它是jQuery对Promises接口的实现。jQuery的所有Ajax操作函数,默认返回的就是一个deferred对象

    2. Promises是异步操作的通用接口,扮演代理人(proxy)的角色,将异步操作包装成具有同步操作特性的特殊对象。异步操作的典型例子就是Ajax操作、网页动画、web worker等等。

    3. 由于JavaScript单线程的特点,如果某个操作耗时很长,其他操作就必需排队等待。为了避免整个程序失去响应,通常的解决方法是将那些排在后面的操作,写成“回调函数”(callback)的形式。这样做虽然可以解决问题,但是有一些显著缺点:

    > 回调函数往往写成函数参数的形式,形成所谓的“持续传递风格”(即参数就是下一步操作,Continuation-passing style),导致函数的输入和输出非常混乱,整个程序的可阅读性差;

    > 回调函数往往只能指定一个,如果有多个操作,就需要改写回调函数。

    > 除了正常的报错机制,错误还可能通过回调函数的形式返回,增加了除错和调试的难度。

    > 正常的函数输入和输出可以区分得很清楚,回调函数使得函数的输出不再重要。

    Promises就是为了解决这些问题而提出的,它的主要目的就是取代回调函数,成为非同步操作的解决方案。它的核心思想就是让非同步操作返回一个对象,其他操作都针对这个对象来完成。比如,假定ajax操作返回一个Promise对象。

    有关Promises对象的使用,可以参见上面的网站。

    这里解决问题,主要采用的是Deferred对象将Ajax返回的数据进行封装。在主线程中,采用回调函数的方式,进一步处理返回的数据,以及线程中下面的程序。

    具体使用如下:

    //主线程
    $('.btn').click(function() {
      //这里使用layui框架实现动态效果
      document.querySelector('.chartes').showLoading({
        text: '正在加载数据...'
      });
      $.when(getData()).done(function(data) { 
        document.querySelector('.chartes').hideLoading();
        alert(data);
      });
    });

    //被调用的Ajax方法
    function getData() { 
       var defer = $.Deferred(); //初始化一个Deferred对象
       $.ajax({ 
       url : '',
       async : true, // true异步。false同步
       success : function(data) { 
           defer.resolve(data); //resolve表示已完成状态
         } 
      }); 
      //promise()方法表示在原来的deferred对象上返回另一个deferred对象,
      //后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),
      //从而使得执行状态不能被改变。
      return defer.promise();
     }

    所以,以上是通过Deferred对象的链式操作得以解决,学习了...

    特别注意的是:以上用法只能在jQuery版本高于1.5.0的版本中,因为低于1.5.0,返回的是XHR对象,无法进行链式操作, 而Deferred对象可以进行链式操作。

    Deferred对象的链式操作详见阮一峰老师的博客:https://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

  • 相关阅读:
    ASP.NET MVC中你必须知道的13个扩展点
    ASP.NET MVC扩展库
    AutoFac简介
    中小型研发团队架构实践十:应用监控怎么做?
    IDEA+Mybatis-generator代码生成工具
    IDEA+EasyCode实现代码生成
    myeclipse中导入的js文件报错(出现红叉叉,提示语法错误)
    Ibatis中常见错误解决方案
    注解
    structs常见错误
  • 原文地址:https://www.cnblogs.com/Archie2018/p/13755554.html
Copyright © 2020-2023  润新知