前端技术栈二(promise&模块化编程)

一、promise

1 Promise****基本介绍

  • 传统的Ajax异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的Callback Hell
  • 为了解决上述的问题,Promise对象应运而生,在EMCAScript 2015当中已经成为标准Promise是异步编程的一种解决方案。
  • 从语法上说,Promise是一个对象,从它可以获取异步操作的消息
  • 一句话**: Promise是异步编程的一种解决方案,可以解决传统Ajax****回调函数嵌套问题**

2 应用实例

**2.1需求分析/**图解

2.2 代码实现

2.2.1 json

创建****D:\idea_java_projects\es6\promise\data\monster.json

创建****D:\idea_java_projects\es6\promise\data\monster_detail_1.json

2.2.2 使用ajax传统方式
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax多次请求</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        $.ajax({
            url:"data/monster.json",
            success(resultData){
               console.log("第一次ajax请求,我们拿到了monster基本信息=",resultData);

               //进行第二次请求,此时就出现了ajax的嵌套
                $.ajax({
                    url: `data/monster_detail_${resultData.id}.json`,
                    success(resultData) {
                        console.log("第二次ajax请求,我们拿到了monster详细信息=",resultData);
                    },
                    error(err) {
                        console.log("第二次出现异常=",err)
                    }
                })
            },
            error(err){
                console.log("出现异常=",err)
            }
        })

    </script>
</head>
<body>

</body>
</html>
2.2.3 使用promise方式
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用promise完成多次ajax请求</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //先请求到monster.json
        let p =new Promise((resolve,reject)=>{
            //创建promise对象需要传入一个箭头函数
            //(resolve,reject)参数列表,如果请求成功调用resolve函数,失败调用reject函数
            //箭头函数体仍然是通过jquery发出ajax
            //发出ajax请求
            $.ajax({
                url:"data/monster.json",
                success(resultData){
                    console.log("promise发出的第一次ajax monster的基本信息=",resultData);
                    resolve(resultData);
                },
                error(err){
                    //console.log("promise发出的异步请求出现错误=",err)
                    reject(err);
                }
            })
        })

        //这里我们可以继续编写请求成功后的业务
        p.then(resultData=>{
            console.log("p.then得到了resultData",resultData);
            return  new Promise((resolve, reject) => {//如果没有return 那么这里的error捕获不到给p
                $.ajax({
                    url: `data/monster_detail_${resultData.id}.json`,
                    success(resultData) {
                        console.log("promise发出的第二次ajax monster的详细信息=",resultData)
                        resolve(resultData)

                    },
                    error(err) {
                        //console.log("promise第二次发出的异步请求出现错误=",err)
                        reject(err)
                    }
                })
            })

        }).then((resultData=>{
            console.log("p.then().then,resultData",resultData)
            //可以在这里发出第三次请求
        }))
            .catch(err=>{//这里可以对多次ajax的异常进行处理
            console.log(err)
        })
    </script>
</head>
<body>

</body>
</html>
2.2.4**使用promise代码优化****/**重排
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>promise 代码重排</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        /**
         * 这里我们将重复的代码,抽出来,编写一个方法 get *
         * @param url ajax 请求的资源
         * @param data ajax 请求携带的数据
         * @returns {Promise<unknown>}
         *
         * */
        function get(url,data) {
            return new Promise((resolve, reject) => {
                $.ajax({
                    url:url,
                    data:data,
                    success(resultData){
                        resolve(resultData);
                    },
                    error(err){
                        reject(err);
                    }
                })
            })
        }

        //需求
        //先获取monster.json
        //获取monster_detail1.json
        //进入第三次
        get("data/monster.json").then(resultData=>{
            //第一次ajax成功后的处理位置
            console.log(resultData);
            return get(`data/monster_detail_${resultData.id}.json`);
        }).then(resultData=>{
            //第二次成功后的处理代码
            console.log("第二次成功后的结果=",resultData);
            //如果还需要下一把
            //return get(url,data)以此类推
        }).catch(err=>{
            console.log(err);
        })

    </script>
</head>
<body>

</body>
</html>
2.2.5 注意事项和使用细节
  • 如果返回的是Promise对象,可以继续执行**.then()**
  • **.then((data)=>{})data数据是上一次正确执行后resolve(data)**返回传入的
  • 通过多级**.then()**可以对异步请求分层次请求,实现代码重排,代码逻辑更加清晰合理
  • 通过多级**.then()后面的.catch((err) => {})**可捕获发生异常,便于调试

3 Promise****课后练习

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>homework</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        function get(url,data) {
            return new Promise((resolve, reject) => {
                $.ajax({
                    url:url,
                    data:data,
                    success(resultData){
                        resolve(resultData);
                    },
                    error(err){
                        reject(err);
                    }
                })
            })
        }
        get("data/student_100.json").then(resultData=>{
            console.log("第1=",resultData);
            return get(`data/class_${resultData.class_id}.json`);
        }).then(resultData=>{
            console.log("第2=",resultData);
            return get(`data/school_${resultData.school_id}.json`);
        }).then(resultData=>{
            console.log("第3=",resultData);
        }).catch(err=>{
            console.log(err);
        })
    </script>
</head>
<body>

</body>
</html>

二、模块化编程

1介绍

1.1基本介绍

  • 传统非模块化开发有如下的缺点:****(1)命名冲突 (2)文件依赖[代码演示]
  • Javascript代码越来越庞大,Javascript引入模块化编程**,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块**
  • **Javascript使用"模 块"module)的概念来实现模块化编程,**解决非模块化编程问题
  • 模块化 也是ES6的新特性

1.2 示意图

1.3 模块化编程分类

  • CommonJS模块化规范/ES5****的写法
  • ES6****模块化规范

2 CommonJS****模块编程

2.1 介绍

  • 每个js文件就是一个模块,有自己的作用域。在文件中定义的变量、函数、类**/对象,都是私有的,对其他js文件不可见**
  • **CommonJS使用module.exports={}/exports={}导出 模块,使用let/const名称=****require("xx.js")**导入模块

2.2 应用实例

2.2.1 需求说明
  • **编写****functions.js ,该文件有函数,变量,常量,对象,**数组。。。
  • 要求在use.js ,可以使用到function.js中定义的 函数**/变量/常量/**对象
  • 请使用模块化编程的方式完成**,**尽量将各种写法都写一下
2.2.2 思路分析**/**图解
2.2.3 代码实现

function.js

javascript 复制代码
//定义对象,变量,常量,函数
const sum=function (a,b) {
    return parseInt(a)+parseInt(b);

}
const sub=function (a,b) {
    return parseInt(a)-parseInt(b);
}
let name="林然";

const PI=3.14;

const monster={
    name:"牛魔王",
    age:500,
    hi(){
        console.log("我是牛魔王,你好");
    }
}

//导出
/*
1. module.exports 导出模块
2. 把你需要导出的数据, 写入到 {}中即可
3. 可以全部导出,也可以部分导出
4. 理解:相当于把我们导出的数据,当做一个对象
5. 如果属性名和函数/变量/对象..名字相同,可以简写
6. 有些前端, 简写 module.exports={} 成 exports={}
*/
module.exports={
    sum:sum,
    sub,//简写
    myname:name
}

use.js

html 复制代码
//导入
//1. 在 es5 中, 我们通过 require 就包 对应.js 中的
//数据/对象,引入
//2. 我们使用的时候,通过 m.属性 就可以使用
//3. 如果我们导入时,不需要所有的,可以导入部分数据
const m=require("function");
console.log(m.myname);
console.log(m.sub(2,3));

//3. 如果我们导入时,不需要所有的,可以导入部分数据
const {sub,sum} =require("./function");
console.log(sub(1,3))
console.log(sum(1,3))

要看运行效果,需要 Node 环境 , node 环境我们后面搭建 , 只要 use.js 可以解析 sum
sub 说明是正确的

3 ES6****模块编程

3.1 介绍

  • **ES6使用(1)export {名称/对象/函数/变量/常量}(2)export定义【对象】={}(3)**export default {}
  • 导出模块
  • **使用import {} from "xx.js"[对应(1)(2)]/import名称form "xx.js"**导入模块

3.2 应用实例**-**批量导出形式

3.2.1 需求说明
  • **编写****common.js ,该文件有函数,变量,常量,**对象
  • 要求在use_common.js ,可以使用到common.js中定义的 函数**/变量/常量/**对象
  • 请使用ES6模块化编程的方式完成
3.2.2 思路分析**/**图解

common.js

javascript 复制代码
//定义对象,变量,常量,函数
const sum=function (a,b) {
    return parseInt(a)+parseInt(b);

}
const sub=function (a,b) {
    return parseInt(a)-parseInt(b);
}
let name="林然";

const PI=3.14;

const monster={
    name:"牛魔王",
    age:500,
    hi(){
        console.log("我是牛魔王,你好");
    }
}
//es6 的导出模块/数据
/**
 * 老师解读
 * 1. export 就是导出模块/数据
 * 2. 可以全部导出,也可以部分导出
 */
export {
    sum,
    sub,
    name
}

use_common.js

javascript 复制代码
//导入
/**
 *
 * 1. 我可以{} 来接收导出的数据
 * 2. 可以全部接收,也可以选择的接收
 * 3. 细节: 这时要求导入的名称和导出的名称一致
 */
import {sum,name,sub} from "./common"
console.log(name);

3.3 应用实例**-**其它导出形式

common2.js

javascript 复制代码
//定义对象,变量,常量,函数
//定义对象,变量,常量, 函数
//定义 sum 函数时,就直接导出
//如果在定义时,导出的数据, 在导入时,要保持名字一致
export const sum=function (a,b) {
    return parseInt(a)+parseInt(b);

}
const sub=function (a,b) {
    return parseInt(a)-parseInt(b);
}
let name="林然";

const PI=3.14;

const monster={
    name:"牛魔王",
    age:500,
    hi(){
        console.log("我是牛魔王,你好");
    }
}
//es6 的导出模块/数据
/**
 * 老师解读
 * 1. export 就是导出模块/数据
 * 2. 可以全部导出,也可以部分导出
 */
export {
    sum,
    sub,
    name
}

use_common2.js

javascript 复制代码
//导入
/**
 *
 * 1. 我可以{} 来接收导出的数据
 * 2. 可以全部接收,也可以选择的接收
 * 3. 细节: 这时要求导入的名称和导出的名称一致
 */
import {sum} from "./common2"
console.log(sum(1,3));

common3.js

javascript 复制代码
//定义对象,变量,常量, 函数
//演示默认导出
//如果是默认导出, 导入的时候,使用的语法
//可以这里理解, 类似把 {} 当做一个对象导出
export default {
    sum(a,b) {
        return parseInt(a) + parseInt(b);
    },sub(a,b) {
        return parseInt(a) - parseInt(b);
    }
}

use_common3.js

javascript 复制代码
//导入默认导出模块/数据
//好处是 m 名称是可以自己指定的.
//因为 m 名字, 程序员可以自己指定,因此我们就可以解决名称冲突问题
import m from "./common3";
//使用 m.xx
console.log(m.sub(80,90));

3.4 注意事项和使用细节

  • ES6的模块化无法在Node.js中执行,需要用Babel转码ES5****后再执行

  • export不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象

  • 没有导出的不能使用

  • es6有导出方式较多,不同的导出方式对导入方式也有一定影响

4 课后作业

4.1 作业1

相关推荐
zqx_71 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己1 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称2 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色2 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2342 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河2 小时前
CSS总结
前端·css
BigYe程普3 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H3 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍3 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai3 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端