深刻理解并正确使用$.post的同步和异步请求

举报
幸福科技 发表于 2021/12/26 00:18:41 2021/12/26
【摘要】 今晚花了三个多小时,重构了一个$.ajaxForm的同步和异步请求写法,感觉特别有成就感,故记录下来,以加深理解和熟练使用。其实,在学习和使用JavaScript中,$.ajax($.post和$.get)的同步和异步请求要深刻理解才能正确使用。

ajax中根据async的值不同分为同步(async = false)和异步(async = true),默认情况下async是true

[代码]

<script>
    $.ajax({
        type: "post",
        url: "path",
        cache: false,
        async: false,
        dataType: "json",
        success: function (result) {
            function1()
            {
                //todo
            };
        }
    });
    function2()
    {
        //todo
    };
</script>

[ajax同步和异步的理解]

一、同步请求:(false)
       同步请求即是当前发出请求后,浏览器什么都不能做,必须得等到请求完成返回数据之后,才会执行后续的代码,相当于是排队,前一个人办理完自己的事务,下一个人才能接着办。也就是说,当javascript代码加载到当前ajax的时候会把页面里所有的代码停止加载,页面处于一个假死状态,当这个ajax执行完毕后才会继续运行其他代码,页面解除假死状态(即当ajax返回数据后,才执行后面的function2)。 
二、异步请求:(true)
       异步请求就当发出请求的同时,浏览器可以继续做任何事,ajax发送请求并不会影响页面的加载与用户的操作,相当于是在两条线上,各走各的,互不影响。一般默认值为true,异步。异步请求可以完全不影响用户的体验效果,无论请求的时间长或者短,用户都在专心的操作页面的其他内容,并不会有等待的感觉。
三、同步和异步的区别:
异步:在异步模式下,当我们使用ajax发送完请求后,可能还有代码需要执行。这个时候可能由于种种原因导致服务器还没有响应我们的请求,但是因为我们采用了异步执行方式,所有包含ajax请求代码的函数中的剩余代码将继续执行。如果我们是将请求结果交由另外一个JS函数去处理的,那么,这个时候就好比两条线程同时执行一样。
同步:在同步模式下,当我们使用ajax发送完请求后,后续还有代码需要执行,我们同样将服务器响应交由另一个js函数去处理,但是这时的代码执行情况是:在服务器没有响应或者处理响应结果的JS函数还没有处理完成return时,包含请求代码的函数的剩余代码是不能够执行的。就好比单线程一样,请求发出后就进入阻塞状态,知道接触阻塞余下的代码才会继续执行。

[html]

<form method="post" action="{:url('banji/doaddgrade')}" name="save_form" id="save_form">
    <input type="hidden" name="school_id" id="school_id" value="{$school.id}">
    <input type="hidden" name="school_code" value="{$school.school_code}">
    <input type="hidden" name="pid" value="0">
    <div class="ncap-form-default">
        <dl class="row">
            <dt class="tit">
                <label for="banjiName">年级名称</label>
            </dt>
            <dd class="opt">
                <div class="input-group">
                    <input name="banjiName" id="banjiName" value="" class="input-txt" type="text" style="width: 100px !important;" />
                    <p>规范名称:一年级,二年级,......</p>
                </div>
            </dd>
        </dl>
        <dl class="row">
            <div class="bot">
                <input type="submit"  class="ncap-btn-big ncap-btn-green" value="添加年级" style="width:120px;!important; height: 35px;" />
            </div>
        </dl>
      </div>
</form>

[JavaScript]

<script>
    $(function(){
        $('#save_form').ajaxForm({
            beforeSubmit: checkForm, // 此方法主要是提交前执行的方法,根据需要设置
            success: complete, // 这是提交后的方法
            dataType: 'json'
        });

        function checkForm(){
            var flag=false;
            var school_id=$('#school_id').val();
            var banjiName=$('#banjiName').val();
            $.ajaxSettings.async = false;
            $.post("{:url('admin/banji/checkdata')}",{"banjiName":banjiName,"school_id":school_id},function (res){
                if(res==1){
                    layer.tips(banjiName+'已经存在!', '#banjiName');
                    flag=false;
                }else {
                    flag=true;
                }
            },"json");
            $.ajaxSettings.async = true;
            return flag;
        }
        function complete(res){
            if(res.data==0){
                layer.msg('添加失败,请重新尝试', {
                    offset: 't',
                    anim: 6
                });
            }else{
                layer.msg('添加成功', {
                    offset: 't',
                    anim: 6
                });
                setTimeout(function () {
                    layer.confirm('现在开始添加班级吗?', {icon: 3}, function(index){
                        layer.close(index);
                        var id=$('#school_id').val();
                        window.location.href='{:url("admin/banji/add")}?school_id='+id;
                    });
                    }, 2000);
            }
        }
    });
</script>

[PHP]

/**
 * @return int  
 * 查检年级名称是否存在
 */
function checkdata(){
    $where = [
        'banjiName' => input('banjiName'),
        'school_id' => input('school_id'),
    ];
    $res=db('banji')->where($where)->find();
    if(!empty($res)){
        return 1;
    }else{
        return 0;
    }
}
/***
 * @return int
 * 年级添加逻辑
  */
public function doaddgrade()
{
    if (input('post.')) {
    $model =model('banji');
    $grade=mb_substr(input('banjiName'),0,1);
    $banji_code=0;
    switch ($grade){
        case '一':
            $banji_code =1;
        break;
        case '二':
            $banji_code =2;
            break;
        case '三':
            $banji_code =3;
            break;
        case '四':
            $banji_code =4;
            break;
        case '五':
            $banji_code =5;
            break;
        case '六':
            $banji_code =6;
            break;
        case '七':
            $banji_code =7;
            break;
        case '八':
            $banji_code =8;
            break;
        case '九':
            $banji_code =9;
            break;
        default:
    }
    $data = [
        'school_id' => input('school_id'),
        'school_code' => input('school_code'),
        'pid' => 0,
        'banjiName' => input('banjiName'),
        'banji_code'=>$banji_code,
    ];
    $result= $model->insert($data);
    return $result;
    }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。