async_await封装JQuery的Ajax请求,解决多层回调问题

后端

.properties文件

server.servlet.context-path: /jmw

controller层

package com.example.demo.controller;

import com.example.demo.entity.Person;
import com.example.demo.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;

@Controller
@RequestMapping("/promise")
public class PromiseAjaxTestController {

    @GetMapping("/init")
    public ModelAndView init() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("promiseTest");
        return modelAndView;
    }

    @PostMapping("/test")
    @ResponseBody
    public Student testAjax() throws Exception {

        Student student = new Student();
        student.setAge(10);
        student.setName("jiafeitian");
        student.setBirthday(new Date());
        student.setTest("test");
        student.setSex("男");

        // 模拟后台请求的耗时操作
        Thread.sleep(3000);

        // 模拟服务器系统异常
        // int a = 1 / 0;
        return student;
    }

    @PostMapping("/param")
    @ResponseBody
    public Person param(@RequestParam("name") String userName, @RequestParam("age") String age) throws Exception {

        Person person = new Person();
        person.setId("1");
        person.setName(userName + age);
        person.setMail("fengyehong1221@foxmail.com");
        // 模拟后台请求的耗时操作
        Thread.sleep(2000);
        return person;
    }
}

前端

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>封装Ajax请求title>
head>
<body>
    <button id="btn">点击发送Ajax请求button>
body>
<script th:src="@{/js/jquery.min.js}">script>
<script th:inline="javascript" type="text/javascript">

    // 上下文对象
    const ctxPath = [[${#httpServletRequest.getContextPath()}]];

    // 自己封装好的Ajax函数
    async function doAjax(url, param) {
		// 定义一个Promise对象
        return await new Promise(function(resolve, reject) {
            $.ajax({
                url: `${ctxPath}${url}`,
                type: "post",
                data: JSON.stringify(param),
                timeout: 50000,
                dataType: "json",
                contentType: 'application/json;charset=utf-8',
                success: function (data) {
                    // 使用表格的方式对后端返回的json数据进行展示,更加直观
                    console.table(data);
                    // 将后端返回的数据放入Promise对象中,从而将回调函数从success中剥离出来
                    resolve(data);
                },
                complete: function (data) {
                    // 当请求完成之后,data是一个对象,存储着状readyState,responseJSON,status等各种信息
                    const {status} = data;
                    console.log(`请求成功,状态码为${status}`);
                },
                error: function (request, textStatus, errorThrown) {
                    // 当请求发送错误,例如服务器内部错误的时候,将相关信息放入Promise的reject对象中
                    reject(request);
                    // 发生错误的时候进行页面跳转,显示错误表示页面
                    window.location = `${ctxPath}/error/init`;
                }
            });
        });
    }

    // 点击按钮,请求后端的数据
    $("#btn").on("click", async function () {

        const param = {
            name: 'mail',
            age: 10
        };

        /*
        * 发送ajax请求,获取后端数据的响应,通过封装Ajax函数从而避免回调函数的写法,更加直观
        * 我们在doAjax方法内部进行了error处理,跳转错误页面.如果不跳转的话,需要在此try...catch
        * */
        const {name, sex, age} = await doAjax('/promise/test', param);

        // 将上一次Ajax请求得到的数据拼接成新的参数,再一次发送Ajax请求
        const params = new URLSearchParams();
        params.append('name', name);
        params.append('sex', sex);
        params.append('age', age);
        // 我们封装了Ajax函数,所以不需要使用回调的方式去处理具体业务
        const userInfo = await doAjax(`/promise/param?${params.toString()}`, {});
        console.log(userInfo);  // {id: "1", name: "jiafeitian10", mail: "fengyehong1221@foxmail.com"}
    });
script>
html>

你可能感兴趣的