前端多层回调问题解决方案之$.Deferred

javascript引擎是单线程的,但是通过异步回调可以实现IO操作并行执行能力,当业务逻辑复杂的时候我们就进入回调地狱。

本文讲得ajax是在jquery1.5以前的版本,目的旨在让我们理解延迟对象的应用场景,jquery1.5之后,ajax默认就是延迟对象,可以进行链式操作

举例:

a(funtion(){
    b(funtion(){
        c(funtion(){
            d(funtion(){
                e(funtion(){
                    f(funtion(){
                        g(funtion(){
                            finish();
                        });
                    });
                });
            });
        });
    });
});      

这还是比较简单的操作,如果每个回调函数还有N多操作,那么更加头疼了。

解决方法:通过jQuery的when().done()实现

1. 函数a,b,c,d,e,f,g都这样写

function a(){
    var dtd = $.Deferred();

    //这里延迟操作,可能是ajax,也可能是setTimeout
    $.post(url,{},function(data){
        ....
        alert("执行完毕!");
      dtd.resolve(); // 改变Deferred对象的执行状态
    }) ;

    return dtd.promise();
}

2. 使用

$.when(
    a(),
    b(),
    c(),
    d(),
    e(),
    f(),
    g()
).done(finish).fail() ;

PS: 除了$.when().done()组合,还有一种组合$.when().then()。

done是在when中的延迟对象dtd都resolve的时候才回执行done中的操作,then是延迟对象有一个resolve就执行。类似于“与”和“或”。

如上的例子,如果a函数里面的ajax请求返回的不是我们想要的结果,我们不想让done执行,应该怎么做呢?

function a(){
    var dtd = $.Deferred();

    //这里延迟操作,可能是ajax,也可能是setTimeout
    $.post(url,{},function(data){
        if(data == 1){
            dtd.resolve(); // 改变Deferred对象的执行状态
        }else{
            dtd.reject(); // 作用和resolve正好相反
        }      
    });

    return dtd.promise();
}

如果a函数服务器返回的是1, 那么done可以执行,如果不是1,那么不会执行done,而是立即执行fail。

如果这里是then那么不会受到影响,只要a,b,c,d,e,f,g有一个resolve。

还有一个函数$when().always(),这个不管when中resolve还是reject,最后都会执行always。

文章转自: http://www.myjscode.com/page/article10.html

时间: 2024-11-09 10:39:18

前端多层回调问题解决方案之$.Deferred的相关文章

避免多层回调,Node.js异步模块Async初使用

原来写的一个分页查询,回调了好几层. exports.list = function(req,res) { var params = {}; var current_page = common_util.get_param_value(req,'current_page','Number',1); var page_size = common_util.get_param_value(req,'page_size','Number',10); var start_index = common_u

避免多层回调,Node.js异步库Async使用(series)

未使用Async之前coffeescript写的代码: exports.product_file_add = (req,res) -> if !req.param('file_id') return res.json({'flag':'error','msg':'请先上传文件再保存!'}) file_type = req.param('file_type') #判断产品和文件类型,限制上传的数量 params = {} params.product_code = req.param('produ

nodejs Async 使用方法(解决多层回调嵌套)

由于nodejs是异步处理的,有时我们想同步从mysql里取出数据,最后在处理逻辑 就需要用到此扩展: 此扩展可以避免多层回调: 安装方法: npm install async 使用方法: 1.parallel 多个函数并行执行 1 var Async = require('async'); 2 3 Async.parallel( 4 [ 5 function(callback){ 6 // 此处查询数据库代码 7 DaoUser.getUserByID(userId, function(err

javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方案

我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越深,代码可读性就会越差. $.ajax({ url: url, data: dataObject, success: function(){ console.log("I depend on ajax result."); }, error: function(){} }); consol

前端常见跨域解决方案(全)

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交 2.) 资源嵌入: <link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链 3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场

前端常见跨域解决方案

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交 2.) 资源嵌入:<link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链 3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景

前端跨域问题解决方案

背景: 同源策略:NetSpace公司引入,基于浏览器安全,防止浏览器收到XSS.CSFR等攻击.同源,即协议+域名+端口完全一致. 同源策略限制的行为: Cookie.LocalStorage和IndexDB无法读取 DOM和JS对象无法获取 Ajax请求不能发送 解决方案: 方案一:JSONP 原理:通过script标签引入的js不受同源策略的限制,而XmlHttpRequest对象受到同源策略的影响.可以加载跨域服务器上的脚本,用JSONP获取的不是JSON数据,而是可以直接运行的JS脚本

rem - 移动前端自适应适配布局解决方案和比较(转载)

原文链接:http://caibaojian.com/mobile-responsive-example.html 互联网上的自适应方案到底有几种呢?就我个人实践所知,有这么几种方案:· 固定一个某些宽度,使用一个模式,加上少许的媒体查询方案使用flexbox解决方案使用百分比加媒体查询使用rem淘宝最近开源的一个框架和网易的框架有同工之异.都是采用rem实现一稿解决所有设置自适应.在没出来这种方案之前,第一种做法的人数也不少.类似以下说到的拉钩网.看一下流云诸葛的文章. 1. 简单问题简单解决

javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式

我们先来看一下编写AJAX编码常常遇到的几个问题: 1.因为AJAX是异步的,全部依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套.ajax等异步操作越多,嵌套层次就会越深.代码可读性就会越差. $.ajax({ url: url, data: dataObject, success: function(){ console.log("I depend on ajax result."); }, error: function(){} }); consol