ES6异步编排Promise与模块化


在 JavaScript 的世界中, 所有代码都是单线程执行的。 由于这个“缺陷”, 导致 JavaScript 的所有网络操作, 浏览器事件, 都必须是异步执行。 使用Promise可以解决这个问题。

一、Promise异步编排

1.异步编排案例

案例需求: 用户登录, 并展示该用户的各科成绩。 在页面发送两次请求:

  1. 查询用户, 查询成功说明可以登录。
  2. 查询用户成功, 查询科目。
  3. 根据科目的查询结果, 获取成绩。

分析: 此时后台应该提供三个接口, 一个提供用户查询接口, 一个提供科目接口, 一个提 供各科成绩接口, 为了渲染方便, 最好响应 json 数据。 在这里就不编写后台接口了, 而 是提供三个 json 文件, 直接提供 json 数据, 模拟后台接口:

	user.json:
	{
    
    
	"id": 1,
	"name": "zhangsan",
	"password": "123456"
	}
	 
	user_corse_1.json:
	{
    
    
	"id": 10,
	"name": "chinese"
	} 
	
	corse_score_10.json:
	{
    
    
	"id": 100,
	"score": 90
	}

不使用ES6实现:

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
...

    <script>
        $.ajax({
     
     
            url: "mock/user.json",
            success(data) {
     
     
                console.log("查询用户: ", data);
                $.ajax({
     
     
                    url: `mock/user_corse_${
       
       data.id}.json`,
                    success(data) {
     
     
                        console.log("查询到课程: ", data);
                        $.ajax({
     
     
                            url: `mock/corse_score_${
       
       data.id}.json`,
                            success(data) {
     
     
                                console.log("查询到分数: ", data);
                            },
                            error(error) {
     
     
                                console.log("出现异常了: " + error);
                            }
                        });
                    },
                    error(error) {
     
     
                        console.log("出现异常了: " + error);
                    }
                });
            },
            error(error) {
     
     
                console.log("出现异常了: " + error);
            }
        });
    </script>

在这里插入图片描述

使用ES6实现:

   <script>
        // 1.使用Promise封装异步操作
        let p = new Promise((resolve, reject) => {
     
     
            // 2. 异步操作
            $.ajax({
     
     
                url: "mock/user.json",
                success: function (data) {
     
     
                    console.log("查询用户成功:", data)
                    resolve(data)
                },
                error: function (err) {
     
     
                    reject(err);
                }
            });
        });

        p.then((obj) => {
     
     
            return new Promise((resolve, reject) => {
     
     
                $.ajax({
     
     
                    url: `mock/user_corse_${
       
       obj.id}.json`,
                    success: function (data) {
     
     
                        console.log("查询用户课程成功:", data)
                        resolve(data);
                    },
                    error: function (err) {
     
     
                        reject(err);
                    }
                });
            })
        }).then((data) => {
     
     
            console.log("上一步的结果:", data)
            $.ajax({
     
     
                url: `mock/corse_score_${
       
       data.id}.json`,
                success: function (data) {
     
     
                    console.log("查询课程得分成功:", data)

                },
                error: function (err) {
     
     

                }
            });
        })

    </script>

2.使用Promise优化

将Promise封装。

  • 用Promise封装异步操作。
  • 用resolve将成功操作向下传递。
  • 用reject将失败操作向下传递。
   <script>
      // 将Promise封装
        function get(url, data) {
     
     
            return new Promise((resolve, reject) => {
     
     
                $.ajax({
     
     
                    url: url,
                    data: data,
                    success: function (data) {
     
     
                        resolve(data);
                    },
                    error: function (err) {
     
     
                        reject(err)
                    }
                })
            });
        }

        get("mock/user.json")
            .then((data) => {
     
     
                console.log("用户查询成功:", data)
                return get(`mock/user_corse_${
       
       data.id}.json`);
            })
            .then((data) => {
     
     
                console.log("课程查询成功:", data)
                return get(`mock/corse_score_${
       
       data.id}.json`);
            })
            .then((data)=>{
     
     
                console.log("课程成绩查询成功:", data)
            })
            .catch((err)=>{
     
     
                console.log("出现异常",err)
            });

    </script>

二、模块化

模块化是编写大型项目的基础,类似于Java中的导包,JS中没有导包的概念,取而代之的是模块化。

  • export命令:用于规定模块的对外接口。
  • import命令:用于导入其他模块提供的功能。

准备三个JS文件,演示模块化的导入导出:

hello.js

export const util = {
    
    
    sum(a, b) {
    
    
        return a + b;
    }
}

// export不仅可以到处对象,一切JS变量都可以导出.比如基本类型变量,函数,数组,对象.
// export{util}

main.js

import util from "./hello.js"
import {
    
    name,age,add} from "./user.js"


util.sum(1,2);
console.log(name+age);
add(1,3);

user.js

var name = "jack";
var age = "21";
function add(a,b){
    
    
    return a + b;
}

export{
    
    name,age,add}