ajax

第一章:原生AJAX

1.1 AJAX简介

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。

通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据

AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

1.2 XML简介

XML 可扩展标记语言。

XML 被设计用来传输和存储数据。

XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。

1.3 AJAX优缺点

  • 可以无需刷新页面而与服务器进行通信
  • 允许你根据用户事件来更新部分页面部分
  • 没有浏览历史,不能回退
  • 存在跨域
  • SEO不友好

1.4 express框架使用

// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();

// 3.创建路由规则
//request是对请求报文的封装
// response是对响应报文的封装
app.get('/', (req, res) => {
    res.send('hello world')
})

// 4.监听端口监听
app.listen(8000, (req, res) => {
    console.log('服务以及启动,8000端口监听中...');
})

1.5AJAX使用

1) 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
2) 设置请求信息
xhr.open(method, url);
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
3) 发送请求
xhr.send(body) //get 请求不传 body 参数,只有 post 请求使用
4) 接收响应
//xhr.responseXML 接收 xml 格式的响应数据
//xhr.responseText 接收文本格式的响应数据
xhr.onreadystatechange = function (){
	if(xhr.readyState == 4 && xhr.status == 200){
		var text = xhr.responseText;
		console.log(text);
	}
}

xhr.readyState当前请求的状态

  • 0:表示XMLHttprequest实例已经生成,但是open()方法还没有调用。
  • 1:表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定请求头。
  • 2:表示send()方法已经执行,并且头信息和状态码已经收到。
  • 3:表示正在接受服务器传来的body部分的数据
  • 4:表示服务器数据已经完全接收,或者失败了。

第二章:jQuery中的AJAX

2.1 GET请求

$.get(url, [data], [callback], [type])
url:请求的 URL 地址。
data:请求携带的参数。
callback:载入成功时回调函数。
type:设置返回内容格式,xml, html, script, json, text,

2.2 POST请求

$.post(url, [data], [callback], [type])
url:请求的 URL 地址。
data:请求携带的参数。
callback:载入成功时回调函数。
type:设置返回内容格式,xml, html, script, json, text, _default。

第三章:跨域

3.1 同源策略

协议、域名、端口号必须完全相同

3.2 CORS

​ CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

​ CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。

第四章:Axios

特点

  1. 基于 xhr + promise 的异步 ajax 请求库

  2. 浏览器端/node 端都可以使用

  3. 支持请求/响应拦截器

  4. 支持请求取消

  5. 请求/响应数据转换

  6. 批量发送多个请求

常用语法

axios(config): 通用/最本质的发任意类型请求的方式
axios(url[, config]): 可以只指定 url 发 get 请求
axios.request(config): 等同于 axios(config)
axios.get(url[, config]): 发 get 请求
axios.delete(url[, config]): 发 delete 请求
axios.post(url[, data, config]): 发 post 请求
axios.defaults.xxx: 请求的默认全局配置
axios.interceptors.request.use(): 添加请求拦截器
axios.interceptors.response.use(): 添加响应拦截器
axios.create([config]): 创建一个新的 axios(它没有下面的功能)
axios.Cancel(): 用于创建取消请求的错误对象llllll
axios.CancelToken(): 用于创建取消请求的 token 对象
axios.isCancel(): 是否是一个取消请求的错误
axios.all(promises): 用于批量执行多个异步请求
axios.spread(): 用来指定接收所有成功数据的回调函数的方法
axios({
    method:'GET',
    url:'http://localhost:3000/posts/2'
}).then(res=>{
    console.log(res)
})

axios({
    method:'POST',
    url:'http://localhost:3000/posts/2',
    //请求体
    data:{
        title:'dsds',
        author:'zf'
    }
}).then(res=>{
    console.log(res)
})

请求成功

image-20230626083644202

4.1 GET请求

const axios = require('axios');

// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
  .then(function (response) {
    // 处理成功情况
    console.log(response);
  })
  .catch(function (error) {
    // 处理错误情况
    console.log(error);
  })
  .then(function () {
    // 总是会执行
  });

// 上述请求也可以按以下方式完成(可选)
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // 总是会执行
  });  

// 支持async/await用法
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

4.2 POST请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

4.3 拦截器

  1. 说明: 调用 axios()并不是立即发送 ajax 请求, 而是需要经历一个较长的流程
  2. 流程: 请求拦截器2 => 请求拦截器1 => 发ajax请求 => 响应拦截器1 => 响应拦截器 2 => 请求的回调
  3. 注意: 此流程是通过 promise 串连起来的, 请求拦截器传递的是 config, 响应拦截器传递的是 response
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });

4.4 axios对象创建过程模拟

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>axios模拟</title>
</head>
<body>
    <script>
        // 构造函数
        function Axios(config){
            // 初始化
            this.defaults = config
            this.intercepters = {
                request:{},
                response:{}
            }
        }
        // 原型添加相关的方法
        Axios.prototype.request = function(config){
            console.log('发送ajax请求,类型为'+config.method);
        }
        Axios.prototype.get = function(config){
            // 调用request方法
            return this.request({method:'GET'})
        }
        Axios.prototype.post = function(config){
            // 调用request方法
            return this.request({method:'POST'})
        }
        // 声明一个函数
        function createInstance(config){
            // 实例化对象:context身上有defaults,intercepters,也可以调用request,get,post
            let context = new Axios(config)//context.get() 但是不能当作函数使用
            // 创建请求函数
            let instance = Axios.prototype.request.bind(context)//instance是一个函数,instance.get不能用
            // 将Axios.prototype对象中的方法添加到instance函数对象
            // 遍历Axios.prototype
            Object.keys(Axios.prototype).forEach(key =>{
                // console.log(key);    request get post
                instance[key]=Axios.prototype[key].bind(context)  //this.default
            })
            // 为instance函数对象添加属性default和interceptor
            Object.keys(context).forEach(key =>{
                instance[key] = context[key]
            })
            console.dir(instance)
            return instance
        }
        let axios = createInstance()

        // axios({method:'GET'})
        axios.get({})
    </script>
</body>
</html>

4.5 模拟axios发送请求

4.6 模拟axios拦截器

4.7 模拟axios取消请求

第五章:Promise

5.1 Promise的介绍和使用

5.1.1 含义

异步编程的新解决方法

之前都是回调函数。

是一个构造函数,promise对象用来封装一个异步操作可以获取其成功、失败的结果值。

5.1.2 好处

  • 旧的:必须在启动异步任务前指定
  • promise:启动异步任务 => 返回peomise对象 => 给promise对象绑定回调函数。
  • 支持链式调用,解决回调地狱问题。
const p = new Promise((resolve,reject) => {
    setTimeout(() => {
        let n = rand(1,100);
        if(n <=30){
            resolve();  //成功调用成功的方法,将promise对象的状态设置为成功。
        }else{	
            reject()    //失败调用失败的方法,将promise对象的状态设置为失败。
        }
    },1000)
})

//调用then方法,对成功或者失败进行处理

p.then(() => {
    alert('恭喜你抽中奖了,兰博基尼10000元代金券!!');//成功执行。所弹出的内容
},() => {
    alert('再接再厉!!');
})

const p = new Promise((resolve,reject) => {
    setTimeout(() => {
        let n = rand(1,100);
        if(n <=30){
            resolve(n);  //成功调用成功的方法,将promise对象的状态设置为成功。
        }else{	
            reject(n)    //失败调用失败的方法,将promise对象的状态设置为失败。
        }
    },1000)
})

//调用then方法,对成功或者失败进行处理

p.then((value) => {
    alert('恭喜你抽中奖了,兰博基尼10000元代金券!!'+value);//成功执行。所弹出的内容
},(reason) => {
    alert('再接再厉!!'+reason);
})

5.1.3 fs读取文件

const fs = require('fs');
fs.readFile('./content.txt',(err,data) =>{
    if(err) throw err;
    console.log(data.toString());
})

promise封装文件操作

let p = new Promise((resolve, reject) => {
    fs.readFile('./content.txt', (err, data) => {
        // 失败
        if (err) reject(err);
        // 成功
        resolve(data);
    })
})
// 调用then
p.then(value=>{
    console.log(value.toString());
},reason=>{
    console.log(reason);
})

5.1.4 AJAX请求

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>promise 封装ajax</title>
    <!-- 新 Bootstrap5 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css">

<body>
    <div class="container">
        <h1 class="page-header">promise封装操作</h1>
        <button type="button" class="btn btn-primary" id="btn">点击发送AJAX</button>
    </div>
    <script>
        const btn = document.querySelector("#btn");
        btn.addEventListener("click", function () {
            const p = new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                // 初始化,设置类型与URL
                xhr.open('POST', 'http://localhost:8000/server');
                // 设置请求头
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                // 发送,请求体
                xhr.send('a=22&b=2323&c=56&d=2')
                // 事件绑定
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status < 400) {
                            // console.log(xhr.response);
                            resolve(xhr.response);
                        } else {
                            // console.log(xhr.status);
                            reject(xhr.status);
                        }
                    }
                }
            });
            // 调用then
            p.then(value=>{
                console.log(value);
            },reason=>{
                console.log(reason);
            })
        })
    </script>
</body>

</html>

5.1.5 封装一个函数

function mineReadFile(path){
    return new Promise((resolve,reject) => {
        // 读取文件
        require('fs').readFile(path, (err, data) => {
            // 判断
            if(err) reject(err);
            resolve(data);
        })
    })
}

mineReadFile('./content.txt').then(value=>{
    console.log(value.toString());
},reason=>{
    console.log(reason);
})
// utilpromisfy方法

const util = require('util')

const fs = require('fs')

// 返回一个新的函数
let mineReadFile = util.promisify(fs.readFile)

mineReadFile('./content.txt').then(value=>{
    console.log(value.toString());
})

5.1.6 封装AJAX请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function sendAJAX(url){
            return new Promise((resolve,reject)=>{
                const xhr = new XMLHttpRequest();
                xhr.open("GET",url);
                xhr.send();
                xhr.onreadystatechange = function(){
                    if(xhr.readyState===4){
                        if(xhr.status>=200&&xhr.status<300){
                            resolve(xhr.response);
                        }else{
                            reject(xhr.status);
                        }
                    }
                }
            })
        };
        sendAJAX('http://localhost:8000/server')
        .then(value=>{
            console.log(value);
        },reason=>{
            console.log(reason);
        })
    </script>
</body>
</html>

5.2 Promise 理解

5.2.1 状态-PromiseState

  • pending 未决定的
  • resolved / fullfilled 成功
  • rejected 失败

5.2.2 对象的值-PromiseResult

保存着异步任务【成功、失败】的结果

  • resolve
  • reject

5.2.3 promise的基本流程

image-20230624174315167

5.3 Promise API

  1. Promise 构造函数: Promise (excutor) {}

​ (1) executor 函数: 执行器 (resolve, reject) => {}

​ (2) resolve 函数: 内部定义成功时我们调用的函数 value => {}

​ (3) reject 函数: 内部定义失败时我们调用的函数 reason => {}

​ 说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行

  1. Promise.prototype.then 方法: (onResolved, onRejected) => {}

​ (1) onResolved 函数: 成功的回调函数 (value) => {}

​ (2) onRejected 函数: 失败的回调函数 (reason) => {}

​ 说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的 promise 对象

  1. Promise.prototype.catch 方法: (onRejected) => {}

​ (1) onRejected 函数: 失败的回调函数 (reason) => {}

  1. Promise.resolve 方法: (value) => {}

​ (1) value: 成功的数据或 promise 对象

​ 说明: 返回一个成功/失败的 promise 对象

//传入的参数为非promise类型的对象,则返回的结果为成功promise独享
//如果传入的参数为promise对象,则参数的结果决定了resolve的结果
let p1 =Promise.resolve(323)
consoleo.log(p1)

let p2 = Promise(new Promise((resolve,reject)=>{
    reject('Errpr')
}))
p2.catch(reason=>{
    consoel.log(reason)
})
  1. Promise.reject 方法: (reason) => {}

​ (1) reason: 失败的原因

​ 说明: 返回一个失败的 promise 对象

  1. Promise.all 方法: (promises) => {}

​ (1) promises: 包含 n 个 promise 的数组

​ 说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败

  1. Promise.race 方法: (promises) => {}

(1) promises: 包含 n 个 promise 的数组

说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态

5.3.1 修改对象状态

let p = new Promise((resolve,reject) => {
    //1.resolve函数
    //resovle('ok');  //pending => fulfilled(resolved)
    //2.reject函数
    //reject('error'); //pending => rejected
    //3.抛出错误
    //throw '出问题了!'
}) 

一个promise指定多个成功,失败的回调函数,都会调用。

5.3.2 改变promise状态和指定回调谁先谁后?

let p = new Promise((resolve,reject) => {
    resolve('ok')//若其中任务为同步任务,则先改变状态,后then执行。
    setTimeout(() => {
        resolve('ok')//若其中任务为异步任务,则先执行then,后改变状态。
    },1000)
})
p.then(value => {
    
},reason=>{
    
})

(1) 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调

(2) 如何先改状态再指定回调?

​ ① 在执行器中直接调用 resolve()/reject()

​ ② 延迟更长时间才调用 then()

(3) 什么时候才能得到数据?

​ ① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据。

​ ② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据。

5.3.3 then方法的返回结果由什么决定?

let p = new Promise((resolve,reject) => {
    resolve('ok')
})
let result = p.then(value => {  //result的返回对象为一个promise
    //1.抛出错误
    //throw '出了问题'    PromiseState:rejected  PromiseResult:出了问题
    //2.返回结果是非promise对象
    //return 521         PromiseState:fulfilled  PromiseResult:521
    //3.返回结果是promise对象  PromiseState:fulfilled  PromiseResult:sucess
    /*
    	return new Promise((reject,resolve) => {
    		resolve('sucess')
    	})
    */
},reason=>{
    
})

(1) 简单表达: 由 then()指定的回调函数执行的结果决定

(2) 详细表达:

​ ① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常

​ ② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值

​ ③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果

5.3.4 promise如何串联多个操作任务?

(1) promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用

(2) 通过 then 的链式调用串连多个同步/异步任务

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        resolve('ok')
    },1000)
})
p.then(value => {
    return new Promise((resolve,reject) => {
        resolve('success');
    });
}).then(value=>{
    console.log(value)
})

5.3.5 promise 异常传透?

(1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,

(2) 前面任何操作出了异常, 都会传到最后失败的回调中处理

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject('error')
    },1000)
})
p.then(value => {
    return new Promise((resolve,reject) => {
        resolve('success');
    });
}).then(value=>{
    console.log(value)
}).catch(reason=>{
    console.log(reason)    //error
})

5.3.6 中断promise链

let p = new Promise((resolve,reject) => {
    setTimeout(() => {
        reject('error')
    },1000)
})
p.then(value => {
    console.log(111)
    //在此处中断,只输出111
    //有且只有一个方式,在回调函数中返回一个pendding状态的promise对象
    return new Promise(()=>{})
}).then(value=>{
    console.log(222)
}).then(value=>{
    console.log(333)
}).catch(reason=>{
    console.warn(reason)    //error
})

(1) 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数

(2) 办法: 在回调函数中返回一个 pendding 状态的 promise 对象

5.4 Promise自定义封装

5.4.1 定义整体结构

创建promise.js文件

// 1、定义promise方法
function Promise(executor) {
    // 5、添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;

    // 6、保存实例对象的this的值
    const self = this;

    // 3、resolve函数
    function resolve(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return ;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled';//resolved
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
    }
    // 4、reject函数
    function reject(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return ;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
    }

    // 2、[执行器函数] 同步调用
    // executor(resolve, reject);

    // 7、throw 抛出异常,定义try...catch
    try {
        // 2、[执行器函数] 同步调用
        executor(resolve, reject);
    } catch (e) {
        // 修改promise对象状态为失败:, throw"error""   error-->e
        reject(e)
    }


}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    //调用回调函数
    if(this.PromiseState === 'fulfilled'){
        onResolved(this.PromiseResult)
    }
    if(this.PromiseState === 'rejected'){
        onRejected(this.PromiseResult)
    }
}

image-20230625102243373

image-20230625102509065

image-20230625102648731

5.4.2 异步任务

// 1、定义promise方法
function Promise(executor) {
    // 5、添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    this.callback = {}
    // 6、保存实例对象的this的值
    const self = this;
    // 3、resolve函数
    function resolve(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return ;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled';//resolved
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        if(self.callback.onResolved){
            self.callback.onResolved(data)
        }
    }
    // 4、reject函数
    function reject(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return ;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        if(self.callback.onRejected){
            self.callback.onRejected(data)
        }
    }
    // 2、[执行器函数] 同步调用
    // executor(resolve, reject);
    // 7、throw 抛出异常,定义try...catch
    try {
        // 2、[执行器函数] 同步调用
        executor(resolve, reject);
    } catch (e) {
        // 修改promise对象状态为失败:, throw"error"   error-->e
        reject(e)
    }
}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    //调用回调函数
    if(this.PromiseState === 'fulfilled'){
        onResolved(this.PromiseResult)
    }
    if(this.PromiseState === 'rejected'){
        onRejected(this.PromiseResult)
    }
    // 异步任务:同步执行到then。PromiseState为pending,不满足以上判断
    // 判断pending状态
    if(this.PromiseState === 'pending'){
        // !*important  保存回调函数
        //console.log(p)中就有了callback这个回调函数
        // onRejected:reason=>{console.log(reason)}
        // onResolved:value=>{console.log(value)}
        this.callback = {
            onResolved:onResolved,
            onRejected:onRejected
        }
    }
}

5.4.3 指定多个回调的实现

// 1、定义promise方法
function Promise(executor) {
    // 5、添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    this.callbacks = [];
    // 6、保存实例对象的this的值
    const self = this;
    // 3、resolve函数
    function resolve(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return ;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled';//resolved
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        self.callbacks.forEach(item => {
            item.onResolved(data)
        })
    }
    // 4、reject函数
    function reject(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return ;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        self.callbacks.forEach(item => {
            item.onRejected(data)
        })
    }
    // 2、[执行器函数] 同步调用
    // executor(resolve, reject);
    // 7、throw 抛出异常,定义try...catch
    try {
        // 2、[执行器函数] 同步调用
        executor(resolve, reject);
    } catch (e) {
        // 修改promise对象状态为失败:, throw"error"   error-->e
        reject(e)
    }
}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    //调用回调函数
    if(this.PromiseState === 'fulfilled'){
        onResolved(this.PromiseResult)
    }
    if(this.PromiseState === 'rejected'){
        onRejected(this.PromiseResult)
    }
    // 异步任务:同步执行到then。PromiseState为pending,不满足以上判断
    // 判断pending状态
    if(this.PromiseState === 'pending'){
        // !*important  保存回调函数
        //console.log(p)中就有了callback这个回调函数
        // onRejected:reason=>{console.log(reason)}
        // onResolved:value=>{console.log(value)}
        this.callback.push({
            onResolved:onResolved,
            onRejected:onRejected
        });
    }
}

5.4.4 同步任务.then返回结果

image-20230625142740595

image-20230625143112993

5.4.5 异步任务.then返回结果

// 1、定义promise方法
function Promise(executor) {
    // 5、添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    this.callbacks = [];
    // 6、保存实例对象的this的值
    const self = this;
    // 3、resolve函数
    function resolve(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled';//resolved
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        self.callbacks.forEach(item => {
            item.onResolved(data)
        })
    }
    // 4、reject函数
    function reject(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        self.callbacks.forEach(item => {
            item.onRejected(data)
        })
    }
    // 2、[执行器函数] 同步调用
    // executor(resolve, reject);
    // 7、throw 抛出异常,定义try...catch
    try {
        // 2、[执行器函数] 同步调用
        executor(resolve, reject);
    } catch (e) {
        // 修改promise对象状态为失败:, throw"error"   error-->e
        reject(e)
    }
}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    return new Promise((resolve, reject) => {
        //调用回调函数
        if (this.PromiseState === 'fulfilled') {
            try {
                // 获取回调函数的执行结果
                let result = onResolved(this.PromiseResult)
                // 判断resulr 是一个promise类型的对象
                if (result instanceof Promise) {
                    // 是promise类型的对象
                    result.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                } else {
                    //不是promise类型的对象 结果的对象状态为成功
                    resolve(result)
                }
            } catch (e) {
                reject(e)
            }

        }
        if (this.PromiseState === 'rejected') {
            onRejected(this.PromiseResult)
        }
        // 异步任务:同步执行到then。PromiseState为pending,不满足以上判断
        // 判断pending状态
        if (this.PromiseState === 'pending') {
            // !*important  保存回调函数
            //console.log(p)中就有了callback这个回调函数
            // onRejected:reason=>{console.log(reason)}
            // onResolved:value=>{console.log(value)}
            this.callback.push({
                onResolved: function () {
                    try {
                        // 执行成功回调函数
                        let result = onResolved(self.PromiseResult)
                        // 判断结果
                        if (result instanceof Promise) {
                            result.then(v => {
                                resolve(v)
                            }, r => {
                                reject(r)
                            })
                        } else {
                            resolve(result)
                        }
                    } catch (e) {
                        reject(e)
                    }

                },
                onRejected: function () {
                    try {
                        // 执行成失败回调函数
                        let result = onRejected(self.PromiseResult)
                        // 判断结果
                        if (result instanceof Promise) {
                            result.then(v => {
                                resolve(v)
                            }, r => {
                                reject(r)
                            })
                        } else {
                            resolve(result)
                        }
                    } catch (e) {
                        reject(e)
                    }

                }
            });
        }
    })

}

image-20230625144435940

5.4.6 封装函数

Promise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    return new Promise((resolve, reject) => {
        // 封装函数
        function callback(type){
            try {
                // 获取回调函数的执行结果
                let result = type(self.PromiseResult)
                // 判断resulr 是一个promise类型的对象
                if (result instanceof Promise) {
                    // 是promise类型的对象
                    result.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                } else {
                    //不是promise类型的对象 结果的对象状态为成功
                    resolve(result)
                }
            } catch (e) {
                reject(e)
            }
        }
        //调用回调函数
        if (this.PromiseState === 'fulfilled') {
            callback(onResolved)
        }
        if (this.PromiseState === 'rejected') {
            callback(onRejected)    
        }
        if (this.PromiseState === 'pending') {
            this.callback.push({
                onResolved: function () {
                    callback(onResolved)
                },
                onRejected: function () {
                    callback(onRejected)
                }
            });
        }
    })

}

5.4.7 catch方法的封装和异常穿透

// 添加catch方法
Promise.prototype.catch = function(onRejected){
    return this.then(undefined, onRejected)
}
let p = new Promise((resolve,))
let res = p.catch(reson=>{
    console.log(reason)
})
console.log(res)

/**
	Promise{
		PromiseResult:undefined
		PromiseState:"fulfilled"
		callback:[]
		_proto_:Obeject
	}
**/

异常穿透

image-20230625153408152

image-20230625153733390

值传递

image-20230625154211480

5.4.8 resolve封装

// 添加resolve方法
Promise.resolve = function(value){
    return new Promise((resolve,reject)=>{
        if(value instanceof Promise){
            // 是promise
            value.then(v=>{
                resolve(v)
            },r=>{
                reject(r)
            })
        }else{
            resolve(value)
        }
    })
}

5.4.9 reject封装

// 添加reject方法
Promise.reject = function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason)
    })
}

5.4.10 all方法封装

let p1 = new Promise((resolve,reject) =>{
            resolve('ok');
        })
        let p2 = Promise.resolve('sucess');
        let p3 = Promise.resolve('oh year');
        // 调用all方法:p1,p2,p3,都是成功的结果组成的数组
		//有一个失败了,则result是一个失败的promise对象,失败的结果,是数组中失败的结果
        let result = Promise.all([p1,p2,p3])
        console.log(result);


image-20230625161446825

// all方法封装
Promise.all = function(promises){
    // 返回结果为promise
    return new Promise((resolve,reject)=>{
        // 遍历
        let count = 0;
        let arr =[];
        for(let i=0 ; i<promises.length ; i++){
            promises[i].then(v=>{
                // 每一个promise对象都成功
                count++;
                arr[i] = v;
                if(count ===peomises.length){
                    // 修改状态
                    resolve()
                }
            },r=>{
                reject(r)
            })
        }
    })
}

5.4.11 race方法的封装

let p1 = new Promise((resolve,reject) =>{
            resolve('sucess');
        })
        let p2 = Promise.resolve('sucess');
        let p3 = Promise.resolve('oh year');
        // 调用race方法:谁先改变,状态和结果就依谁!!
        let result = Promise.race([p1,p2,p3])
        console.log(result);
// race方法
Promise.race = function(promises){
    return new Promise((resolve, reject)=>{
        for(let i=0; i<promises.length; i++){
            promises[i].then(v=>{
                resolve(v);
            },r=>{
                reject(r);
            })
        }
    })
}

5.4.12 .then回调函数的异步执行

5.4.13 class版本封装



// 1、定义promise方法
function Promise(executor) {
    // 5、添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    this.callbacks = [];
    // 6、保存实例对象的this的值
    const self = this;
    // 3、resolve函数
    function resolve(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled';//resolved
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onResolved(data)
            })
        });

    }
    // 4、reject函数
    function reject(data) {
        // 状态只能修改一次
        if (self.PromiseState !== 'pending') return;
        // 6.1修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        // 6.2设置对象结果值(promiseResult)
        self.PromiseResult = data;
        // 调用成功的回调函数
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onRejected(data)
            })
        });

    }
    // 2、[执行器函数] 同步调用
    // executor(resolve, reject);
    // 7、throw 抛出异常,定义try...catch
    try {
        // 2、[执行器函数] 同步调用
        executor(resolve, reject);
    } catch (e) {
        // 修改promise对象状态为失败:, throw"error"   error-->e
        reject(e)
    }
}

// 添加then方法
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    if (typeof onRejected !== "function") {
        onRejected = reason => {
            throw reason;
        }
    }
    if (typeof onResolved !== "function") {
        onResolved = value => value
        //value => {return value}
    }
    return new Promise((resolve, reject) => {
        // 封装函数
        function callback(type) {
            try {
                // 获取回调函数的执行结果
                let result = type(self.PromiseResult)
                // 判断resulr 是一个promise类型的对象
                if (result instanceof Promise) {
                    // 是promise类型的对象
                    result.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                } else {
                    //不是promise类型的对象 结果的对象状态为成功
                    resolve(result)
                }
            } catch (e) {
                reject(e)
            }
        }
        //调用回调函数
        if (this.PromiseState === 'fulfilled') {
            setTimeout(() => {
                callback(onResolved)
            })

            // try {
            //     // 获取回调函数的执行结果
            //     let result = onResolved(this.PromiseResult)
            //     // 判断resulr 是一个promise类型的对象
            //     if (result instanceof Promise) {
            //         // 是promise类型的对象
            //         result.then(v => {
            //             resolve(v)
            //         }, r => {
            //             reject(r)
            //         })
            //     } else {
            //         //不是promise类型的对象 结果的对象状态为成功
            //         resolve(result)
            //     }
            // } catch (e) {
            //     reject(e)
            // }

        }
        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onRejected)
            })

            // try{
            //     let result = onRejected(this.PromiseResult)
            //     if(result instanceof Promise){
            //         result.then(v=>{
            //             resolve(v)
            //         },e=>{
            //             reject(r)
            //         })
            //     }else{
            //         resolve(result)
            //     }
            // }catch(e){
            //     reject(e)
            // }

        }
        // 异步任务:同步执行到then。PromiseState为pending,不满足以上判断
        // 判断pending状态
        if (this.PromiseState === 'pending') {
            // !*important  保存回调函数
            //console.log(p)中就有了callback这个回调函数
            // onRejected:reason=>{console.log(reason)}
            // onResolved:value=>{console.log(value)}
            this.callback.push({
                onResolved: function () {
                    callback(onResolved)
                    // try {
                    //     // 执行成功回调函数
                    //     let result = onResolved(self.PromiseResult)
                    //     // 判断结果
                    //     if (result instanceof Promise) {
                    //         result.then(v => {
                    //             resolve(v)
                    //         }, r => {
                    //             reject(r)
                    //         })
                    //     } else {
                    //         resolve(result)
                    //     }
                    // } catch (e) {
                    //     reject(e)
                    // }

                },
                onRejected: function () {
                    callback(onRejected)
                    // try {
                    //     // 执行成失败回调函数
                    //     let result = onRejected(self.PromiseResult)
                    //     // 判断结果
                    //     if (result instanceof Promise) {
                    //         result.then(v => {
                    //             resolve(v)
                    //         }, r => {
                    //             reject(r)
                    //         })
                    //     } else {
                    //         resolve(result)
                    //     }
                    // } catch (e) {
                    //     reject(e)
                    // }

                }
            });
        }
    })

}

// 添加catch方法
Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected)
}

// 添加resolve方法
Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            // 是promise
            value.then(v => {
                resolve(v)
            }, r => {
                reject(r)
            })
        } else {
            resolve(value)
        }
    })
}

// 添加reject方法
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}

// all方法封装
Promise.all = function (promises) {
    // 返回结果为promise
    return new Promise((resolve, reject) => {
        // 遍历
        let count = 0;
        let arr = [];
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                // 每一个promise对象都成功
                count++;
                arr[i] = v;
                if (count === peomises.length) {
                    // 修改状态
                    resolve()
                }
            }, r => {
                reject(r)
            })
        }
    })
}

// race方法
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                resolve(v);
            }, r => {
                reject(r);
            })
        }
    })
}

封装class

class Promise {
    // 构造方法
    constructor(executor) {
        // 5、添加属性
        this.PromiseState = 'pending';
        this.PromiseResult = null;
        this.callbacks = [];
        // 6、保存实例对象的this的值
        const self = this;
        // 3、resolve函数
        function resolve(data) {
            // 状态只能修改一次
            if (self.PromiseState !== 'pending') return;
            // 6.1修改对象的状态(promiseState)
            self.PromiseState = 'fulfilled';//resolved
            // 6.2设置对象结果值(promiseResult)
            self.PromiseResult = data;
            // 调用成功的回调函数
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onResolved(data)
                })
            });
        }
        // 4、reject函数
        function reject(data) {
            // 状态只能修改一次
            if (self.PromiseState !== 'pending') return;
            // 6.1修改对象的状态(promiseState)
            self.PromiseState = 'rejected';
            // 6.2设置对象结果值(promiseResult)
            self.PromiseResult = data;
            // 调用成功的回调函数
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onRejected(data)
                })
            });
        }
        // 2、[执行器函数] 同步调用
        // executor(resolve, reject);
        // 7、throw 抛出异常,定义try...catch
        try {
            // 2、[执行器函数] 同步调用
            executor(resolve, reject);
        } catch (e) {
            // 修改promise对象状态为失败:, throw"error"   error-->e
            reject(e)
        }
    }
    // then方法封装
    then(onResolved, onRejected){
        const self = this;
        if (typeof onRejected !== "function") {
            onRejected = reason => {
                throw reason;
            }
        }
        if (typeof onResolved !== "function") {
            onResolved = value => value
            //value => {return value}
        }
        return new Promise((resolve, reject) => {
            // 封装函数
            function callback(type) {
                try {
                    // 获取回调函数的执行结果
                    let result = type(self.PromiseResult)
                    // 判断resulr 是一个promise类型的对象
                    if (result instanceof Promise) {
                        // 是promise类型的对象
                        result.then(v => {
                            resolve(v)
                        }, r => {
                            reject(r)
                        })
                    } else {
                        //不是promise类型的对象 结果的对象状态为成功
                        resolve(result)
                    }
                } catch (e) {
                    reject(e)
                }
            }
            //调用回调函数
            if (this.PromiseState === 'fulfilled') {
                setTimeout(() => {
                    callback(onResolved)
                })
            }
            if (this.PromiseState === 'rejected') {
                setTimeout(() => {
                    callback(onRejected)
                })
            }
            // 异步任务:同步执行到then。PromiseState为pending,不满足以上判断
            // 判断pending状态
            if (this.PromiseState === 'pending') {
                this.callback.push({
                    onResolved: function () {
                        callback(onResolved)
                    },
                    onRejected: function () {
                        callback(onRejected)
                    }
                });
            }
        })
    }
    // catch方法
    catch(onRejected) {
        return this.then(undefined, onRejected)
    }
    // 添加resolve方法,是一个类.
    static resolve(value) {
        return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                // 是promise
                value.then(v => {
                    resolve(v)
                }, r => {
                    reject(r)
                })
            } else {
                resolve(value)
            }
        })
    }
    static reject(reason) {
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }
    static all(promises) {
        // 返回结果为promise
        return new Promise((resolve, reject) => {
            // 遍历
            let count = 0;
            let arr = [];
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v => {
                    // 每一个promise对象都成功
                    count++;
                    arr[i] = v;
                    if (count === peomises.length) {
                        // 修改状态
                        resolve()
                    }
                }, r => {
                    reject(r)
                })
            }
        })
    }
    static race(promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v => {
                    resolve(v);
                }, r => {
                    reject(r);
                })
            }
        })
    }
}

5.5 async和await

5.5.1 async函数

  • 函数返回值为promise对象
  • promise对象的结果由async函数执行的返回值决定
  • 和then差不多
async function main(){
    //1.如果返回值是一个非promise类型的数据
    //return 521 成功
    //2.如果返回的是一个promise对象
    /**
    return new Promise((resolve,reject) =>{
    	resolve('ok')
	})
	**/
    //3.抛出异常
    //throw  'sdsd'
}
let result = main()
console.log(result)

5.5.2 await函数

  • await右侧的表达式一般为promise对象,但是也可以是其他的值
  • 如果表达式是promise对象,await返回的是promise成功的值
  • 如果表达式是其他值,直接将此值作为await的返回值

注意

1、await必须写在async函数中,但async函数中可以没有await

2、如果await的promise失败了,就会抛出异常,需要通过try..catch捕获处理

5.5.3 结合使用

const fs = require('fs');
const util = require('util');
const mineReadFile = util.promisify(fs.readFile)
async function main() {
    try {
        let data1 = await mineReadFile('./1nnn.html');
        let data2 = await mineReadFile('./2nnn.html');
        let data3 = await mineReadFile('./3nnn.html');
        console.log(data1 + data2 + data3);
    } catch (e) {
        console.log(e);
    }

}
main()
posted @ 2023-06-28 09:22  孤舟蓑衣客  阅读(40)  评论(0)    收藏  举报