欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

js 回调地狱的另类解决方案尝试

程序员文章站 2022-06-15 21:42:24
例如 通过学生获取学生所在学校信息,需要先查询学生所在班级,再通过班级查询所在学校信息。js代码类似写法如下: 写了个类通过设置相关业务信号量来绑定触发的方法,当信号变量改变时就会自动调用相应的方法,改进方法如下: flag 是个信号量设置对象,s.setFlag(flag, "canGetClas ......

例如 通过学生获取学生所在学校信息,需要先查询学生所在班级,再通过班级查询所在学校信息。js代码类似写法如下:

function getstudentschool(id) {
    ajax.get("/test/getstudent", { "studentid": id }, function (student) {
        if (student != null && student.classid != null) {
            ajax.get("/test/getclass", { "classid": student.classid }, function (studentclass) {
                if (studentclass != null && studentclass.schoolid != null) {
                    ajax.get("/test/getschool", { "schoolid": studentclass.schoolid }, function (school) {
                        if (school != null) {
                            console.log(school);
                        }
                    });
                }
            });
        }
    });
}
 
//调用入口方法
window.οnlοad= function(){
	getstudentschool(1);
};

  写了个类通过设置相关业务信号量来绑定触发的方法,当信号变量改变时就会自动调用相应的方法,改进方法如下:

function asynflag() {
    if (typeof this.setflag != "function") {
        asynflag.prototype.setflag = function (obj, name, fun) {
            if (obj.hasownproperty(name)) {
                obj[name + "_fun"] = fun;
                return;
            }
            obj[name] = 0;
            obj[name + "_"] = 0;
            object.defineproperty(obj, name, {
                get: function () {
                    return obj[name + "_"];
                },
                set: function (value) {
                    if (value != obj[name + "_"]) {
                        obj[name + "_"] = value;
                    }
                    else
                    {
                        return;
                    }
                    if (obj[name + "_fun"] == null) {
                        obj[name + "_fun"] = fun;
                    }
                    obj[name + "_fun"]();
                }
            });
        };
    }
}
 
var param = { "studentid": 0, "classid": 0, "schoolid": 0 };
var s = new asynflag();
var flag = {};
 
function getstudent()
{
    ajax.get("/test/getstudent", { "studentid": param.studentid }, function (student) {
        if (student != null && student.classid != null) {
            param.classid = student.classid;
            s.setflag(flag, "cangetclass", getclass);
            flag.cangetclass = true;
        } 
    });
}
 
function getclass()
{
    ajax.get("/test/getclass", { "classid": param.classid }, function (studentclass) {
        if (studentclass != null && studentclass.schoolid != null) {
            param.schoolid  = studentclass.schoolid;
            s.setflag(flag, "cangetschool", getschool);
            flag.cangetschool = true;
        }
    });
}
 
function getschool()
{
    ajax.get("/test/getschool", { "schoolid": param.schoolid }, function (school) {
        if (school != null) {
            console.log(school);
        }
    });
}
//调用入口方法
window.onload= function(){
    param.studentid =1;
    getstudent();
};

flag 是个信号量设置对象,s.setflag(flag, "cangetclass", getclass); 设置flag拥有cangetclass属性,并且该属性绑定函数getclass,  当第一个ajax获得数据后设置信号并改变信号量触发绑定的getclass函数,flag对象中会自动创建cangetclass,

cangetclass_, 两个属性和一个cangetclass_fun方法来实现当cangetclass改变时调用cangetclass_fun=getclass。

以上代码实际测试可行。

代码已上传github https://github.com/safajim/asynflag
————————————————
版权声明:本文为csdn博主「皮皮虾大侠」的原创文章,遵循 cc 4.0 by-sa 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/asa_jim/article/details/86648199