例如 通过学生获取学生所在学校信息,需要先查询学生所在班级,再通过班级查询所在学校信息。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

js 回调地狱的另类解决方案尝试的更多相关文章

  1. JavaScript异步编程__“回调地狱”的一些解决方案

    异步编程在JavaScript中非常重要.过多的异步编程也带了回调嵌套的问题,本文会提供一些解决“回调地狱”的方法. setTimeout(function () { console.log('延时触 ...

  2. javascript回调地狱真的只能Promise来解决吗?js回调地狱,Promise。

    javascript的灵活在于函数可以当作函数的参数来传递,以及它的异步回调思想.但是这就带了一个很严重的问题,那就是回调次数过多,会影响代码结构,多层嵌套影响代码的可阅读性,也不便于书写. 举个例子 ...

  3. JS回调函数(深入篇)

    <有些错别字> 在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中 ...

  4. JS回调函数深入篇

    <有些错别字> 在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中 ...

  5. 【JavaScript】 使用Async 和 Promise 完美解决回调地狱

    很久以前就学习过Async和Promise,但总是一知半解的. 今天在写NodeJS的时候,发现好多第三方库使用回调,这样在实际操作中会出现多重回调,这就是传说中的JS回调地狱. 举个例子 有一个方法 ...

  6. 避免Node.js中回调地狱

    为了解决这个阻塞问题,JavaScript严重依赖于回调,这是在长时间运行的进程(IO,定时器等)完成后运行的函数,因此允许代码执行经过长时间运行的任务. downloadFile('example. ...

  7. js中的回调地狱 Callback to Hell

        本文重点:解决方式:1.promise  2. 拆解 function:将各步拆解为单个的 function  3. 通过 Generator 函数暂停执行的效果方式 4. 通过ES8的异步函 ...

  8. js中的回调函数 和promise解决异步操作中的回调地狱问题。

    回调函数 : 函数作为参数传递到另外一个函数中.简单数据类型和引入数据类型中的数组和对象作为参数传递大家肯定都不陌生,其实引用数据类型中的函数也是可以的. 事实上大家见到的很多,用到的也很多,比如jQ ...

  9. js动画实现&&回调地狱&&promise

    1. js实现动画 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

随机推荐

  1. 有奖投票丨HC2019开发者关注的TOP10问题你最想听哪个?

    目前,人工智能已经成为广大开发者重点关注的技术领域.然而,随着人工智能技术的快速发展,AI应用场景复杂度在与日俱增,算法调教也亟需不断成熟,这些都为开发者们带来了更多全新的挑战.如何快速把握前沿技术的 ...

  2. MySQL必知必会(Insert into)

    ########################## # Populate customers table ########################## INSERT INTO custome ...

  3. Balls in the Boxes

    Description Mr. Mindless has many balls and many boxes,he wants to put all the balls into some of th ...

  4. ZOJ-1709

    The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSu ...

  5. 基于iCamera测试mt9m034 1280X960 高动态相机模块小结

    基于iCamera测试mt9m034 高动态相机模块小结 首先看看此模块的特性 mt9m034 高动态 CMOS模块 1280*960像素 5.48 V/lux-sec >115db 摄像头模块 ...

  6. ES6语法中的class、extends与super的原理

    class 首先, 在JavaScript中, class类是一种函数 class User {    constructor(name) { this.name = name; }    sayHi ...

  7. matlab安装出现“无法访问所在网络位置”的正确解决办法

    今天安装matlab时出现了如下错误:无法访问您试图使用的功能所在的网络位置,单击"确认"重试或者在下面输入包含"vcredist.msc"的文件夹路径. (由 ...

  8. Django 11

    目录 功能配置设计 跨站请求伪造CSRF 什么是CSRF 如果实现CSRF 如何避免CSRF CSRF相关的两个装饰器 auth模块 常用方法 扩展auth_user表中的字段 功能配置设计 实现类似 ...

  9. java_计算个人所得税

    // import java.util.Scanner;public class Test10{ public static void main(String[] args){ // 创建Scanne ...

  10. Vue AES+MD5加密 后台解密

    前端VUE vue项目中安装crypto-js npm install crypto-js --save-dev CryptoJS (crypto.js) 为 JavaScript 提供了各种各样的加 ...