2023/1/11 Web前端Promise从入门到精通

news2024/11/23 8:00:36

ES6引入的进行异步编程的解决方案,从语法上说它是一个构造函数。
异步编程包括但不限于:文件操作、数据库操作、AJAX、定时器

为什么要用Promise?
之前进行异步编程直接通过回调函数的方式进行,会导致回调地狱。

  • 回调函数:作为参数的函数
  • 回调地狱:回调函数里面嵌套回调函数
    在这里插入图片描述
    具体理解:
    从语法上说,Promise是一个构造函数
    从功能上说,Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值

1 Promise的初体验

实现:
点击按钮, 1s 后显示是否中奖(30%概率中奖)
若中奖弹出 恭喜您中奖
若未中奖弹出 谢谢参与

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <h2 class="page-header">Promise初体验</h2>
    <button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script type="text/javascript">
    function rand(m, n) {
        return Math.ceil(Math.random() * (n - m + 1) + m - 1);
    }

    // 点击按钮,2s后显示是否中奖(30%概率中奖)
    // 若中奖弹出恭喜恭喜,奖品为10万 RMB 劳斯莱斯优惠券;若未中奖弹出再接再厉

    // 获取元素对象
    const btn = document.querySelector('#btn');
    // 绑定单机事件
    btn.addEventListener('click', function () {
        // 30%
        // 获取 1 - 100随机数
        // setTimeout(() => {
        //     let n = rand(1, 100)
        //     if (n <= 30) {
        //         alert('恭喜恭喜,奖品为10万 RMB 劳斯莱斯优惠券')
        //     } else {
        //         alert('再接再厉')
        //     }
        // }, 1000)

        // resolve 解决 - 函数类型的数据 - success
        // reject  拒绝 - 函数类型的数据 - fail
        const p = new Promise((resolve, reject) => {
            // Promise 对象 - 可以包裹一个异步任务
            setTimeout(() => {
                let n = rand(1, 100)
                if (n <= 30) {
                    resolve(n) // 将 promise 对象的状态设置为 『成功』
                } else {
                    reject(n) // 将 promise 对象的状态设置为 『失败』
                }
            }, 1000);
        })
        // 调用then方法
        // 成功就调用第一个回调函数,失败调用第二个回调
        p.then((value) => {
            alert('恭喜您中奖,您的中奖号码为' + value);
        }, (reason) => {
            alert('谢谢参与,您的号码为' + reason);
        })
    })


</script>

</body>
</html>

在这里插入图片描述
Promise构造函数的参数是一个包含异步操作的函数

new Promise((resolve, reject) => {})

函数有两个参数,resolve和reject,这两个参数同样也是函数形式

  • resolve在函数内的异步操作成功时调用,会将Promise对象状态设置为成功,并且将成功的结果传递给对象,供then的回调函数使用。
  • reject在函数内的异步操作失败时调用,会将Promise对象状态设置为失败,并且将失败的原因传递给对象,供then的回调函数使用。
const p = new Promise((resolve, reject) => {
   let n = rand(1, 100)
   if (n <= 30) {
       resolve(n) // 将 promise 对象的状态设置为 『成功』
   } else {
       reject(n) // 将 promise 对象的状态设置为 『失败』
   }
     p.then((value) => {
         alert('恭喜您中奖,您的中奖号码为' + value);
     }, (reason) => {
         alert('谢谢参与,您的号码为' + reason);
     })

Promise.then()函数具有两个参数,都是函数形式

  • 第一个回调函数在Promise状态为成功时调用
    其参数value是Promise的构造函数中回调函数中成功的结果
  • 第二个回调函数在Promise状态为失败时调用
    其参数reason是Promise的构造函数中回调函数中失败的原因

2 fs读取文件

基础回调函数形式:

const fs = require('fs')
 fs.readFile('D:\\code\\wt-promise\\src\\components\\HelloWorld.vue', (err, data) => {
     if (err) {
         throw err;
     } else {
         console.log(data.toString())
     }
 })
  • readFile的第一个参数是文件路径
  • 第二个参数是一个回调函数,err表示出错信息,data表示获取到的数据
  • 函数主体则根据参数进行操作即可

Promise封装后:

const fs = require('fs')
let p = new Promise((resolve, reject) => {
    fs.readFile('D:\\code\\wt-promise\\src\\components\\HelloWorld.vue', (err, data) => {
        // 如果出错
        if (err) reject(err);
        // 如果成功
        resolve(data);
    });
});

p.then(value => {
    console.log(value.toString());
}, reason => {
    console.log(reason);
})

3 AJAX请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div cLass="container">
    <h2 class="page-header">Promise封装AJAX 操作</h2>
    <button class="btn btn-primary" id="btn">点击发送AJAX</button>
</div>
<script>
    //接口地址 https://api.apiopen.top/getJoke
    //获取元素对象
    const btn = document.querySelector('#btn');
    btn.addEventListener('click', function () {
        // 1.创建对象
        const xhr = new XMLHttpRequest();
        // 2.初始化
        xhr.open('GET', 'https://www.baidu.com/');
        // 3.发送
        xhr.send();
        // 4.处理响应结果
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                // 判断响应状态码
                if (xhr.status >= 200 && xhr.status < 300) {
                    // 控制台输出响应体
                    console.log(xhr.response);
                } else {
                    // 控制台输出响应体
                    console.log(xhr.status);
                }
            }
        }
    });
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div cLass="container">
    <h2 class="page-header">Promise封装AJAX 操作</h2>
    <button class="btn btn-primary" id="btn">点击发送AJAX</button>
</div>
<script>
    //接口地址 https://api.apiopen.top/getJoke
    //获取元素对象
    const btn = document.querySelector('#btn');

    btn.addEventListener('click', function () {
        // 创建Promise对象
        const p = new Promise((resolve, reject) => {
            // 1.创建对象
            const xhr = new XMLHttpRequest();
            // 2.初始化
            xhr.open('GET', 'https://api.apiopen.top/getJoke');
            // 3.发送
            xhr.send();
            // 4.处理响应结果
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    // 判断响应状态码
                    if (xhr.status >= 200 && xhr.status < 300) {
                        // 控制台输出响应体
                        resolve(xhr.response);
                    } else {
                        // 控制台输出响应体
                        reject(xhr.status);
                    }
                }
            }
        });
        p.then(value => {
            console.log(value);
        }, reason => {
            console.warn(reason);
        });
    });
</script>
</body>
</html>

4 Promise封装fs读取文件操作【真没发现!!!!】

封装一个函数 mineReadFile 读取文件内容

  • 参数: path 文件路径
  • 返回: promise 对象
function mineReadFile(path) {
    return new Promise((resolve, reject) => {
        // 读取文件
        require('fs').readFile(path, (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
}

其返回一个Promise对象

调用函数,使用Promise.then()的方法

mineReadFile('./resource/content.txt')
    .then((value) => {
        console.log(value.toString());
    }, (reason) => {
        console.log(reason);
    });
  • 原始需要在readFile的参数里面指定回调函数
    在这里插入图片描述

  • 使用Promise后,可以在mineReadFIle后面的then函数中指定回调函数,解决回调地狱问题

5 util.promisify方法进行promise风格转化

作用:自动将异步操作封装成一个Promise
在这里插入图片描述

//  引入util模块
const util=require('util');
// 引入fs模块
const fs=require('fs');
//返回一个新的函数
let mineReadFile=util.promisify(fs.readFile);

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

7 Promise对象状态属性介绍

状态:实例对象中的一个属性 【PromiseState】,三个值

  • pending 待定
  • resolved / fullfilled 成功
  • rejected 失败
    状态改变:
  • 只能由pending改成resolved 或 pending改成rejected
  • 状态只能改变一次

实例对象中的另一个属性 【PromiseResult】- 对象的值
保存着异步任务『成功/失败』的结果

  • resolve
  • reject
  • 只有resolve、reject可以修改其值

8 Promise工作流程

在这里插入图片描述

  • 调用构造函数前,Promise的状态为pending
  • 调用构造函数,执行异步操作
成功则执行resolved(),修改Promise对象状态为resolved,在then函数中回调onResolved,返回一个新的Promise对象
失败则执行rejected(),修改Promise对象状态为rejected,在then函数中回调onRejected,返回一个新的Promise对象

9 Promise的API

1 构造函数-then-catch

  • Promise构造函数:Promise(executor){}
executor函数:执行器函数 (resolve,reject)=>{ }

resolve函数:{ } 内部异步操作成功时我们调用的函数 value => { }
reject函数:{ } 内部异步操作失败时我们调用的函数  reason => { }

PS!!!
executor会在Promise内部立即同步调用,意味着代码执行到Promise的对象创建时就会执行其构造函数的回调函数,再执行下面的代码:
在这里插入图片描述
如这段代码先输出111再输出222
而执行器的异步操作,就在执行器中按照规定的异步顺序执行

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

Promise.prototype.then()的prototype表示then是Promise的实例对象的方法,如果没有prototype则表示then是promise函数对象的方法(类似于静态方法)

参数为两个回调函数: onResolved,onRejected
onResolved函数:成功的回调函数:(value)=>{ }
onRejected函数:失败的回调函数:(reason)=>{ }
  • Promise.prototype.catch()方法:(onRejected)=>{ }
只指定异步操作失败的回调函数,参数只有onRejected
onRejected函数:失败的回调函数:(reason)=>{ }
  • Promise.resolve方法:(value)=>{ }

resolve是Promise类的静态方法,不需要实例就能调用

作用:接受一个参数,直接返回一个成功或失败的Promise对象,快速将一个值封装成一个Promise对象

在这里插入图片描述
在这里插入图片描述
特点:

如果传入的参数为非Promise对象,则返回的结果为状态为成功的Promise对象
如果传入的参数为Promise对象,则返回的结果为状态为传入的Promise对象的状态,返回结果的值为传入Promise的值

在这里插入图片描述
在这里插入图片描述

  • 这边会报错是因为传入的Promise状态为rejected,这需要Promise有处理错误的回调函数,通过P2.catch((reason)=>{} )补上回调函数即可

  • 相反,如果传入的Promise的状态为resolved,则不需要特意补一个回调函数也不会报错

  • Promise.reject()方法:(reason)=>{}

 作用:返回一个值为reason的,状态为rejected的Promise对象

在这里插入图片描述
无论传入什么都返回一个状态为失败Promise,即使传入一个成功的Promise对象,返回的Promise的值是传入的成功的Promise对象,但是返回Promise的状态还是失败

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

作用:返回一个新的Promise,当所有Promise都成功,返回的Promise状态为成功,其结果为所有Promise的结果组成的一个数组;当存在失败的Promise,返回的Promise的状态为失败,其结果为失败的Promise的结果

成功情况:
在这里插入图片描述
在这里插入图片描述
失败情况
在这里插入图片描述
在这里插入图片描述

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

promises:包含 n 个 promise 的数组
注:返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    })
    let p2 = Promise.resolve('Success');
    let p3 = Promise.resolve('Oh Yeah');

    const result = Promise.race([p1, p2, p3]);

    console.log(result);

</script>
</body>
</html>

在这里插入图片描述

10 Promise关键问题

1 如何修改对象的状态

三种方式

  • 在构造函数中直接调用 resolve 函数
  • 在构造函数中直接调用 reject 函数
  • 在构造函数中直接抛出错误:throw Error
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        // 1. resolve 函数
        // resolve('ok'); // pending   => fulfilled (resolved)
        //2. reject 函数
        // reject("error");// pending  =>  rejected
        //3. 抛出错误
        throw '出问题了';
    });

    console.log(p);


</script>
</body>
</html>

在这里插入图片描述

2 一个Promise指定多个成功/失败的回调函数,都会调用吗

当promise状态改变为对应状态时都会调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('OK');
    });

    //指定回调 - 1
    p.then(value => {
        console.log(value);
    });

    //指定回调 - 2
    p.then(value => {
        alert(value);
    });


</script>
</body>
</html>

在这里插入图片描述

3 改变Promise状态和指定回调函数谁先谁后

问题简化:Promise代码运行时,resolve先执行还是then先执行

注意,指定回调和执行回调函数是不一样的,指定回调类似于p.then()中声明有哪些回调函数,执行回调则是在状态确定之后执行之前指定的回调

两种情况都有可能

  • 先改状态(执行reslove reject )再指定回调:
执行器中是一个同步操作,那么就先做执行器中的操作`再执行then语句即指定回调`
	例如直接在执行器中直接调用 resolve()/reject()
执行器中是一个异步操作,延长更长时间才调用then()同样可以达到效果
  • 先指定回调再改变状态
执行器中是异步操作时,会先执行then - 指定回调(但是不执行回调),再回头根据异步操作的顺序进行处理

什么时候才能得到数据? - 回调函数什么时候执行

  • 如果先改变状态,那么当指定回调时,回调函数就会被调用,得到数据
  • 如果先指定回调,那么当状态发生改变时,回调函数才被调用得到数据

如下为同步:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('OK');
    });

    p.then(value => {
        console.log(value);
    }, reason => {

    })

</script>
</body>
</html>

在这里插入图片描述

如下为异步,需等一秒之后执行:
promise执行器中是一个异步任务,那么就执行then,指定回调;处理执行器中的异步任务,1000ms后改变状态;再执行成功的回调函数,得到数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(value);
    }, reason => {

    })

</script>
</body>
</html>

4 then()方法返回的Promise的对象的状态由什么决定

then方法返回结果由 then()指定的回调函数执行的结果决定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    // 执行 then 方法
    let result = p.then(value => {
    }, reason => {
    });

    console.log(result);


</script>
</body>
</html>

在这里插入图片描述

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    // 执行 then 方法
    let result = p.then(value => {
        //1. 抛出错误
        throw '出了问题';
    }, reason => {
    });
    console.log(result);
</script>
</body>
</html>

在这里插入图片描述

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    // 执行 then 方法
    let result = p.then(value => {
      
        //2. 返回结果是非 Promise 类型的对象
        return 521;
      
    }, reason => {
        // console.warn(reason);
    });

    console.log(result);


</script>
</body>
</html>

在这里插入图片描述

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    });
    // 执行 then 方法
    let result = p.then(value => {
     
        //3. 返回结果是 Promise 对象
        return new Promise((resolve, reject) => {
            // resolve('success');
            reject('error');
        });
    }, reason => {
        // console.warn(reason);
    });

    console.log(result);


</script>
</body>
</html>

在这里插入图片描述

5 Promise如何串联多个操作任务

(1) promise 的 then()返回一个新的 promise, 可以看成 then()的链式调用
(2) 通过 then 的链式调用串连多个同步/异步任务

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        // 第一次执行异步任务
        setTimeout(() => {
            console.log("first mission")
            resolve("1000ms later resolve");
        }, 1000)
    })
    p.then(
        // 返回一个执行异步任务的Promise,从而第二次执行异步任务,再第一次执行完之后才能执行,链式调用避免回调地狱
        (value) => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log("second mission")
                    resolve();
                }, 1000)
            })
        },
    ).then(
        value => {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log("third mission")
                    resolve();
                }, 1000)
            })
        }
    )


</script>
</body>
</html>


在这里插入图片描述

6 异常穿透

(1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,
(2) 前面任何操作出了异常, 都会传到最后失败的回调中处理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(111);
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {   // 在最后指定一个失败的回调
        console.warn(reason);
    });


</script>
</body>
</html>

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
            // reject('Err');
        }, 1000);
    });

    p.then(value => {
        // console.log(111);
        throw '失败啦!';
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {   // 在最后指定一个失败的回调
        console.warn(reason);
    });


</script>
</body>
</html>

在这里插入图片描述

7 如何中断promise链

  • 链式调用过程中,我们希望在某一个then()方法的onResolve回调函数调用过程中,中断Promise的链式调用,只需要返回一个状态为pending的Promise对象

当没有明确返回一个promise对象,then()也会返回一个Promise对象,状态为【resolved】,结果为【underfined】

  • 因为then方法的回调函数调用依据是Promise的状态是resolved或者rejected,没有pending对应的回调函数,所以后面的都没法执行了
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK');
        }, 1000);
    });

    p.then(value => {
        console.log(111);
        //有且只有一个方式
        return new Promise(() => {
        });
    }).then(value => {
        console.log(222);
    }).then(value => {
        console.log(333);
    }).catch(reason => {
        console.warn(reason);
    });

</script>
</body>
</html>

11 async

  • async是一个函数修饰符
  • 函数的返回值是Promise对象
  • Promise对象的结果由async函数执行的返回值决定
和then一样:分成三种情况执行返回值: 是非Promise对象,是一个Promise对象,是抛出异常

在这里插入图片描述

12 await

获取Promise的成功的结果

  • await右侧表达式一般为Promise对象,但也可以是一个其他值
  • 如果表达式时Promise对象,await返回的Promise成功的值
  • 如果表达式是其他值,直接将此值作为await的返回值
await 必须写在 async 函数中,async 函数中可以没有 await
如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="container">
    <h2 class="page-header">Promise初体验</h2>
    <button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
<script type="text/javascript">
    async function main() {
        let p = new Promise((resolve, reject) => {
            // resolve('OK');
            reject('Error');
        })
        //1. 右侧为promise的情况
        // let res = await p;
        //2. 右侧为其他类型的数据
        // let res2 = await 20;
        //3. 如果promise是失败的状态
        try {
            let res3 = await p;
        } catch (e) {
            console.log(e);
        }
    }

    main();
    
</script>

</body>
</html>

在这里插入图片描述

13 async与await结合实践

//回调函数的方式
fs.readFile('D:\\code\\wt-promise\\src\\hello.text', (err, data1) => {
    if (err) throw err;
    fs.readFile('D:\\code\\wt-promise\\src\\hello.text', (err, data2) => {
        if (err) throw err;
        fs.readFile('D:\\code\\wt-promise\\src\\hello.text', (err, data3) => {
            if (err) throw err;
            console.log(data1 + data2 + data3);
        });
    });
});

在这里插入图片描述

//async 与 await
async function main() {
    try {
        // 如果表达式时Promise对象,await返回的Promise成功的值
        let data1 = await mineReadFile('D:\\code\\wt-promise\\src\\hello.text');
        let data2 = await mineReadFile('D:\\code\\wt-promise\\src\\hello.text');
        let data3 = await mineReadFile('D:\\code\\wt-promise\\src\\hello.text');
        console.log(data1 + data2 + data3);
    } catch (e) {
        console.log(e.code);
    }
}

main();

在这里插入图片描述

14 async与await结合发送AJAX请求

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/157868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt扫盲-QMenu理论总结

QMenu理论总结一、概述二、常用操作1. 添加Action2. 信号槽3. 可撕下菜单4. 展示菜单一、概述 QMenu其实就是菜单控件&#xff0c;菜单控件本质上就是一个选择项目。它可以是菜单栏中的下拉菜单&#xff0c;也可以是独立的上下文菜单。当用户单击相应的位置或按下指定的快捷键…

【大数据】第一章:了解Hadoop生态圈

大数据特点&#xff08;4V&#xff09; Volume(大量) 非常非常多&#xff0c;大企业数据接近1EB Velocity(高速) 比如在双十一&#xff0c;数据爆增 Variety(多样) 很多样子的数据&#xff0c;比如&#xff0c;代码&#xff0c;图片&#xff0c;视频&#xff0c;JSON&am…

【C++】八大排序

文章目录前言1. 插入排序2. 希尔排序3. 选择排序4. 堆排序5. 冒泡排序6. 快速排序(重点)6.1 快速排序(hoare版本)6.2 快速排序(挖坑法)6.3 快速排序(前后指针法)6.4 快速排序(非递归)6.5 快速排序(优化)7. 归并排序7.1 归并排序(递归实现)7.2 归并排序非递归实现8. 计数排序排序…

Docker搭建PHP运行环境

目录 Docker 安装 PHP Docker 安装 Nginx ​编辑运行nginx容器 nginx安装成功 Nginx PHP 部署PHP项目 启动 PHP&#xff1a; 启动 nginx&#xff1a; 查看正在运行的容器: 访问域名测试搭建结果 Docker相关命令描述 Docker 安装 PHP 这里我们拉取官方的镜像,标签…

代码随想录算法训练营第8天 344.反转字符串、541. 反转字符串II、剑指Offer58-II.左旋转字符串

代码随想录算法训练营第8天 344.反转字符串、541. 反转字符串II、剑指Offer58-II.左旋转字符串 反转字符串 力扣题目链接(opens new window) 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 对于字符串&#xff0c;我…

Linux驱动开发基础__Linux 系统对中断处理的演进

目录 1 Linux 对中断的扩展&#xff1a;硬件中断、软件中断 2 中断处理原则 1&#xff1a;不能嵌套 3 中断处理原则 2&#xff1a;越快越好 4 要处理的事情实在太多&#xff0c;拆分为&#xff1a;上半部、下半部 5 下半部要做的事情耗时不是太长&#xff1a;tasklet…

154. 滑动窗口

文章目录QuestionIdeasCodeQuestion 给定一个大小为 n≤106 的数组。 有一个大小为 k 的滑动窗口&#xff0c;它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子&#xff1a; 该数组为 [1 3 -1 -3 5 3 6 7]&…

知识点滴 - 数据库视图概念

视图是数据库中一个非常简单的概念&#xff0c;写过SQL的人几乎大致了解视图。本文除了在回顾视图的本质及相关操作知识时&#xff0c;会重点阐述它蕴含的分层思想在数据分析工作中的作用。 1&#xff0c;视图的本质与作用 视图是一个数据库中的虚拟表&#xff0c;它的本质是S…

模板特化与static成员初始化

我们知道在 c 的类中&#xff0c;如果有static成员数据&#xff0c;则需要在类外进行定义&#xff0c;而类内那只是声明。这个在类模板中也是一样的&#xff0c;需要在类外进行定义。普通类模板的 static 数据的初始化&#xff0c;如下代码&#xff1a; template <class T&…

SpringBoot在Controller层接收参数的常用方法(超详细)

前言 在工作中&#xff0c;比如要实现一个功能&#xff0c;前端传什么参数&#xff0c;后端的controller层中怎么接收参数 &#xff0c;封装成了什么实体对象&#xff0c;有些参数是在URL上使用&#xff0c;有些参数是在body上使用&#xff0c;service层中做了什么逻辑&#xf…

数据结构(根据王道整理)

数据结构 文章目录数据结构线性结构与非线性结构链表kmp算法栈二叉树完全二叉树二叉树的存储结构二叉树的访问树的深度二叉树的层次遍历由遍历序列构造二叉树已知后序跟中序建立二叉树线索二叉树序言&#xff08;土办法解决找前驱&#xff09;线索二叉树存储结构中序线索二叉树…

几道基础的二叉树、树的题

几道基础的二叉树、树的题LeetCode144.二叉树的前序遍历思路及实现方法一&#xff1a;递归方法二&#xff1a;迭代LeetCode145.二叉树的后序遍历思路及实现方法一&#xff1a;递归方法二&#xff1a;迭代LeetCode94.二叉树的中序遍历思路及实现方法一&#xff1a;递归方法二&am…

数据结构(2)树状数组

活动 - AcWing 参考&#xff1a;《算法竞赛进阶指南》-lyd 目录 一、概念 1.主要功能 2.实现方式 3. 二、例题 1.树状数组和逆序对 2.树状数组和差分 3. 两层差分 4. 结合二分 一、概念 1.主要功能 树状数组可以完成的功能主要有&#xff1a; 维护序列的前缀和单…

pytest-pytest插件之测试覆盖率pytest-cov

简介 测试覆盖率是指项目代码被测试用例覆盖的百分比&#xff0c;使用pytest-cov插件可以统计测试覆盖率 添加链接描述 安装插件pytest-cov pip install pytest-cov用法 基本用法 –cov的参数是要统计代码覆盖率的源码&#xff0c;我将源码放在mysrc中&#xff0c;test_s…

qiankun微应用加载第三方js跨域报错

当我们在qiankun微应用&#xff0c;引入第三方js脚本时会产生跨域问题并报错&#xff0c;看qiankun的解释&#xff1a;常见问题 - qiankunqiankun会把静态资源的加载拦截&#xff0c;改用fetch方式获取资源&#xff0c;所以要求这些资源支持跨域。虽然qiankun也提供了解决方案&…

react面试题--react入门小案例案例

React入门应该是这样的 源码&#xff1a;https://github.com/dansoncut/React-beginner-tutorial-TeacherEgg.git 视频地址&#xff1a;https://www.bilibili.com/video/BV1be411w7iF/?spm_id_from333.337.search-card.all.click&vd_sourceae42119b44d398cd8fe181740c3e…

Java线程的六种状态

前言&#xff1a;其实线程的状态在操作系统的PCB中就对其进行了描述&#xff0c;但是Java中觉得自带的状态并不是特别好&#xff0c;于是引入了线程在Java中的六种状态。 (1) NEW 安排了工作还未行动&#xff0c;即&#xff1a;Thread对象创建出来了&#xff0c;但是内核的PCB…

开源工具 tomcat

Tomcat 封装了很多HTTP的操作&#xff1a;负责解析 HTTP 协议&#xff0c;解析请求数据&#xff0c;并发送响应数据。 官网 download下的which version&#xff1a; Apache Tomcat - Which Version Do I Want? 可以看tomcat对jdk的版本要求。 启动 启动&#xff1a;双击…

【redis6】第六章(新数据类型)

Bitmaps 简介 现代计算机用二进制&#xff08;位&#xff09;作为信息的基础单位&#xff0c; 1个字节等于8位&#xff0c; 例如“abc”字符串是由3个字节组成&#xff0c; 但实际在计算机存储时将其用二进制表示&#xff0c; “abc”分别对应的ASCII码分别是97、 98、 99&am…

SEO优化收徒站外引蜘蛛软件方法

SEO优化收徒站外引蜘蛛软件方法 今天我们讲解站外引蜘蛛的方法&#xff0c;站外引蜘蛛的方法无非就是五个大点。 第一个是搜索引擎的提交&#xff0c;我们通过是百度资源站展或者 360 或者神马头条&#xff0c;搜狗 bin 等等这样的一个搜索引擎去提交我们的链接。 里面主要是…