回调地狱和Promise

news/2024/7/19 16:41:43 标签: ajax, js, javascript

Promise是ES6中新增的语法,主要是解决原来回调地狱,也就是回调函数多层嵌套问题。

现在我有两个json文件,分别用ajax来请求,但是要求先请求data.json的数据,然后再请求data1.json的数据。

javascript">    $.ajax({
        url: './data1.json',
        dataType: 'json',
        success: function (data) {
            console.log(data);
        }
    })
    
    $.ajax({
        url: './data.json',
        dataType: 'json',
        success: function (data) {
            console.log(data);
        }
    })

显然,上面的代码是无法保证请求顺序的,你可以不断的刷新来试一试,总是不一样的顺序。

那么,自然而然就想到了回调函数(callback),让请求data1的ajax方法放在回调函数中,等data.json数据请求完毕后再执行。

javascript">    function callback() {
        $.ajax({
            url: './data1.json',
            dataType: 'json',
            success: function (data) {
                console.log(data);
            }
        })
    }

    $.ajax({
        url: './data.json',
        dataType: 'json',
        success: function (data) {
            console.log(data);
            callback();
        }
    })

这样子是可以保证请求顺序的。但是,如果我的需求是请求100个这样的json文件,且要保证顺序,那么我是不是就要在一个回调函数中嵌套另外一个回调函数,再在新的回调函数中再嵌套一个回调函数…

如下图所示,这样就成了回调地狱(callback hell)
在这里插入图片描述
为了保证异步函数的执行顺序,不得不使用回调函数嵌套的方法,这样的代码写出来不仅可读性不好,可维护性也很差。试想你愿意修改这样的代码吗?Promise能让我们的代码变得更加优雅。

javascript"> var p2 = new Promise((resolve, reject) => {
            $.ajax({
                url: './data1.json',
                dataType: 'json',
                success: function (data) {
                    resolve(data);
                },
                error: (err) => {
                    reject(err);
                }
            })
        });

        var p1 = new Promise((resolve, reject) => {
            $.ajax({
                url: './data.json',
                dataType: 'json',
                success: (data) => {
                    resolve(data);
                },
                error: (err) => {
                    reject(err);
                }
            })
        });

        p1
            .then((data) => {
                console.log(data);
                return p2;  //return 一个Promise对象,接收的其实是这个对象的两个形参函数.
            }, (err) => {
                console.log('请求失败!', err);
            })

            .then(data => {
                console.log(data);
            }, err => {
                console.log('请求失败!', err);
            })

当请求成功时,把数据给到resolve函数,失败时把错误给到reject函数。
然后用Promise的实例方法then实现resolve方法和reject方法。

在p1中return的值,可以是任意的,但是一般都是一个Promise对象,这样才有意义。虽然返回的是一个Promise对象,但是下一个then方法接收的参数为这个返回的Promise对象中的resolve方法和reject方法。

注意,Promise不是异步的,它只是内部封装了一个异步函数而已。

使用Promise时,通常都会把它封装为一个函数。我们把上面的代码改造一下。

javascript">    function ajaxPromise(ajaxUrl) {
        return new Promise((resolve, reject) => {
            $.ajax({
                url: ajaxUrl,
                dataType: 'json',
                success: (data) => {
                    resolve(data);
                },
                error: (err) => {
                    reject(err);
                }
            })
        })
    }

    ajaxPromise('./data.json')
        .then(data => {
            console.log(data);
            return ajaxPromise('./data1.json');
        }, err => {
            console.log('请求失败!', err);
        })
        .then(data => {
            console.log(data);
        }, err => {
            console.log('请求失败!', err);
        })

这样子的代码,相对于回调函数的层层嵌套,是不是很优雅,很漂亮呢?


http://www.niftyadmin.cn/n/1257988.html

相关文章

201521123096《Java程序设计》第八周学习总结

1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容。 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 实验中使用了scanner方法时,就需要使用sc.close()将其关闭。 1.2截图提交结…

201521123022 《Java程序设计》 第8周学习总结

1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容。 2. 书面作业 Q1.List中指定元素的删除(题目4-1) Q1.1 实验总结 本题要求的是编写covnertStringToList函数代码以及remove函数代码,实验课上老师对本题讲解比…

let关键字

基本语法 和var关键字用法基本一致。 let a 10;let fn function () {console.log(hello)}fn();console.log(a);与var的区别 var关键字会将变量挂载到window对象上,无块级作用域,有变量提升。let关键字不会将变量挂载到window对象上,有独立…

你不知道的if,else

alert&#xff1a; 输出 prompt&#xff1a; 框 confirm&#xff1a; 返回上一级 顺序语句&#xff1a; 从上往下顺着写 分支语句&#xff1a; if else if 循环语句&#xff1a;for循环 while循环 <script type"texe/javascript> if(判断条件) {…

thinkphp-内置标签

判断比较 if                                   <if condition"$name eq 1">                  $this->assign(name,1); 1 <elseif condition"$data.name eq 2" />        …

一个简单的网站(适合课设)

前言 这是我帮同学写的一个很简单的网站&#xff0c;没有后端&#xff0c;主要的技术有jQuery&#xff08;包括Ajax&#xff09;&#xff0c;模仿的是h2j的天猫仿站项目。 可以用于web课设&#xff0c;或者其他前后端交互的界面。下面看下预览图。 由于时间紧&#xff0c;没做…

IIS发布MVC ASP.NET网站

发布网站后&#xff0c;发现无法访问,最后在配置文件上添加一段&#xff1a; <system.codedom> <compilers> <compiler language"c#;cs;csharp" extension".cs" type"Microsoft.CSharp.CSharpCodeProvider,System, Version2.0.0.0, Cu…

js创建模式

工厂模式 function createPerson(name, age, job) {var o new Object();o.name name;o.age age;o.job job;o.sayName function () {alert(this.name);}return o;}var p1 createPerson(zed, 18, Doctor);var p2 createPerson(ls, 19, Engineer);p1.sayName()p2.sayName()…