当前位置: 首页 > news >正文

【ES6】掌握Promise和利用Promise封装ajax

💻 【ES6】掌握Promise和利用Promise封装ajax 🏠专栏:JavaScript
👀个人主页:繁星学编程🍁
🧑个人简介:一个不断提高自我的平凡人🚀
🔊分享方向:目前主攻前端,其他知识也会阶段性分享🍀
👊格言:☀️没有走不通的路,只有不敢走的人!☀️
👉让我们一起进步,一起成为更好的自己!!!🎁

文章目录

  • 【ES6】掌握Promise和利用Promise封装ajax
    • 一. 概念
    • 二. Promise的静态方法
      • (1) all
      • (2) race
      • (3) allSettled (ES2020新增)
      • (4) any
      • (5) Promise的其他方法
    • 三. JavaScript容错处理
      • try...catch...
    • 四. 利用promise封装ajax
    • 五. async和await

【ES6】掌握Promise和利用Promise封装ajax

一. 概念

Promise是ES6 新增的特性

目的:用来解决异步解决回调地狱问题

利用Promise类创建promise实例对象,类的参数是回调函数,回调函数又有两个参数(一般约定为resolve(成功)和reject(失败))

Promise 的基本语法

const 实例对象 = new Promise(回调函数)

eg:

const p = new Promise(function(resolve,reject){});

回调函数中的参数:

  • resolve:成功的回调
  • reject:失败的回调

Promise 的三个状态:

  • 持续:pending
  • 成功:fulfilled
  • 失败:rejected

Promise 的两种转换(三种状态变成两种可能):

  • 从持续状态转换到成功
  • 从持续状态转换到失败

Promise 的实例原型方法:

  • then(函数):成功状态的时候执行的方法
  • catch(函数):失败状态的时候执行的方法
  • finally(函数) :结束时执行的方法,不管状态是成功还是失败,finally都会执行

Promise 的调用方式 (链式调用)

  • 当在第一个then里面返回 一个新的promise对象的时候
  • 可以在第一个then后面继续第二个then
const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000console.log(time);setTimeout(() => {if (time > 3000) {console.log('成功');resolve("success");} else {console.log('失败');reject("reject");}}, 2000);
});
// 成功状态的时候执行
p.then(function (sa) {console.log(sa);
})
// 失败状态的时候执行
p.catch(function (sc) {console.log(sc);
});

使用函数简单封装Promise代码

function fz() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000console.log(time);setTimeout(() => {if (time > 3000) {resolve("success")} else {reject("reject");}}, 2000);});return p;
}
fz().then(function (num) {console.log("1成功", num);
}).then(function (num) {console.log("2成功", num);
}).then(function (num) {console.log("3成功", num);
}).catch(function (num) {console.log('失败', num);
}).finally(function () {console.log('无论最终是成功还是失败,都会执行');
})

二. Promise的静态方法

(1) all

语法:Promise.all([多个 Promise])

作用:用于将多个 Promise 实例,包装成一个新的 Promise 实例,接受一个数组作为参数,只有数组里面的每个状态都变成resolve,则新的 Promise 实例状态才会变成resolve。

function fz1() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000;console.log(time, '第一个请求');setTimeout(() => {if (time > 3000) {resolve({ code: 1, message: '成功' })} else {if (time < 2500) {resolve({ code: 0, message: '失败1' })} else {resolve({ code: 2, message: '失败2' })}}}, time)})return p;
}
function fz2() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000;console.log(time, '第二个请求');setTimeout(() => {if (time > 3000) {resolve({ code: 1, message: '成功' })} else {if (time < 2500) {resolve({ code: 0, message: '失败1' })} else {resolve({ code: 2, message: '失败2' })}}}, time)})return p;
}
function fz3() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000;console.log(time, '第三个请求');setTimeout(() => {if (time > 3000) {resolve({ code: 1, message: '成功' })} else {if (time < 2500) {resolve({ code: 0, message: '失败1' })} else {resolve({ code: 2, message: '失败2' })}}}, time)})return p;
}Promise.all([fz1(), fz2(), fz3()]).then(res => console.log('成功', res)).catch(err => console.log('失败', err))

(2) race

语法:Promise.race([多个promise])

作用:将多个 Promise 实例,包装成一个新的 Promise 实例,接受一个数组作为参数,只要其中有一个实例率先改变状态,则整个的状态就跟着改变。

function fz1() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000;console.log(time, '第一个请求');setTimeout(() => {if (time > 3000) {resolve({ code: 1, message: '成功' })} else {if (time < 2500) {resolve({ code: 0, message: '失败1' })} else {resolve({ code: 2, message: '失败2' })}}}, time)})return p;
}
function fz2() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000;console.log(time, '第二个请求');setTimeout(() => {if (time > 3000) {resolve({ code: 1, message: '成功' })} else {if (time < 2500) {resolve({ code: 0, message: '失败1' })} else {resolve({ code: 2, message: '失败2' })}}}, time)})return p;
}
function fz3() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000;console.log(time, '第三个请求');setTimeout(() => {if (time > 3000) {resolve({ code: 1, message: '成功' })} else {if (time < 2500) {resolve({ code: 0, message: '失败1' })} else {resolve({ code: 2, message: '失败2' })}}}, time)})return p;
}
Promise.race([fz1(), fz2(), fz3()]).then(res => console.log('成功', res)).catch(err => console.log('失败', err))

(3) allSettled (ES2020新增)

语法:Promise.allSettle([多个promise])

作用:方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。

简单理解就是:不管是成功还是失败,都会触发,并会把结果用数组的形式返回,数组里面放着每一个promise的结果

let p1 = new Promise((resolve, reject) => {resolve('1')
});
let p2 = new Promise((resolve, reject) => {reject('2')
});
let p3 = new Promise((resolve, reject) => {reject('3')
});let allSettled = Promise.allSettled([p1, p2, p3]);
allSettled.then((res) => {console.log('then:', res); // 返回数组,数组里面有三个对象,对象里面区分成功和失败的值,状态是正常的。//status:resolve  value  /  status:reject reasonconsole.log(res[0].status); // fulfilledconsole.log(res[0].value); // 1console.log(res[1].status); // rejectedconsole.log(res[1].reason); // 2
});

(4) any

语法:Promise.any([多个promise])

作用:该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。Promise.any()不会因为某个 Promise 变成rejected状态而结束,必须等到所有参数 Promise 变成rejected状态才会结束。

let p1 = new Promise((resolve, reject) => {reject('1')// resolve('1')
});
let p2 = new Promise((resolve, reject) => {// reject('2')resolve('2')
});
let p3 = new Promise((resolve, reject) => {reject('3')
});// 解析:
// 如果遇到成功的请求,通过then返回resolve传递给then对应的值,如果都是失败的状态,最终走catch输出默认的字符( All promises were rejected),执行catch里面的代码,无法获取reject里面传入的值。
let any = Promise.any([p1, p2, p3]);
any.then(res => {console.log('then:', res);
}).catch(msg => {console.log('catch代码'); console.log(msg); //默认的字符All promises were rejected
});

(5) Promise的其他方法

以下两个方法主要是开发人员调试用的

  • resolve()强行把promise的状态改为成功

    let num = 10;
    Promise.resolve(num).then(res => console.log(res))
    console.log(1);
    
  • reject()强行把Promise的状态改为失败

    let num = 10;
    Promise.reject(num).then().catch(res => {console.log(res) // 10
    });
    console.log(1); // 1
    

三. JavaScript容错处理

因为js代码如果出现错误,立刻停止,后续的代码不会执行。

console.log(a); // referenceError:a is not defined  
console.log(1);

所以需要采用方法使js代码出现错误时,不会影响到后续代码

try…catch…

语法1

try {执行代码} catch (err) {执行代码}

使用

首先执行try里面的代码,如果不报错,catch不执行
如果报错,不会抛出错误,而是执行catch,把错误信息给到err。

try {console.log(a);
} catch (e) { //e:try里面如果存在错误,e就是try里面的错误信息console.log(e); // referenceError:a is not defined  console.log('这里是catch的输出'); // 这里是catch的输出
}console.log('后面后续的代码输出'); // 后面后续的代码输出
console.log('后面后续的代码输出'); // 后面后续的代码输出

语法2

try {执行代码} catch (err) {执行代码} finally{执行代码}

:finally里面的语法不管是执行try还是catch,finally里面的代码一定会执行。

try {console.log('a');
} catch (e) { //e:try里面如果存在错误,e就是try里面的错误信息console.log(e); // referenceError:a is not definedconsole.log('这里是catch的输出');
} finally { //收尾的工作,不再使用的对象,变量,设置nullconsole.log('finally一定会执行');
}
/*
输出结果:afinally一定会执行
*/

应用场景-案例

随机生成一个数字,添加判断条件,最终输出成功或失败结果

function fz() {const p = new Promise(function (resolve, reject) {const time = Math.random() * 2000 + 2000console.log(time);setTimeout(() => {if (time > 2500) {resolve("success")} else {reject("reject");}}, 2000);});return p;
}
async function cs() {try {const res1 = await fz();console.log(res1);} catch (err) {const res2 = await fz();console.log(res2);}
}
cs()

四. 利用promise封装ajax

封装前的分析:

/*封装ajax function ajax(options){}调用封装的ajaxajax({})分析封装方案1. 回调函数方式- 将来使用的时候,可能会出现回调地狱2. promise - 后面 then/catch- 也可以用async/await参数1. 请求地址 url 必填2. 请求方式 method,选填(只允许 get post),要么不传,默认值 get3. 是否异步 async,选填  默认true4. 参数 data 选填,默认是'', (允许传查询字符串 和 对象)5. 请求头headers 选填,默认{content-type:'application/x-www-form-urlencoded'}6. 是否解析响应的参数 dataType, 选填 默认是string,  选填 json
*/

封装代码:

// 对象格式转查询字符串格式
function queryString(obj) {let str = ''for (let k in obj) {str += `&${k}=${obj[k]}`}return str.slice(1)
}// 利用闭包保存url基准地址
function createAjax(url) {// 设置一个变量作为基准地址,并长期保存这个变量let baseUrl = url// 封装ajax函数function ajax(options = {}) {// 1.验证参数格式// 1-1.验证url格式:必填if (!options.url) {// 没填抛出错误:'url必填'throw new Error('url必填')}// 1-2.验证method:要么不写,要么get或postif (!(options.method === undefined || /^(get|post)$/i.test(options.method))) {throw new Error('请求方式支持get 和 post')}// 1-3.验证async:要么不写,要么true/false ===> 参数是布尔类型if (!(options.async === undefined || typeof options.async === 'boolean')) {throw new Error('async需要一个布尔值')}// 1-4.验证data:要么不写,支持字符串格式/对象格式if (!(options.data === undefined || typeof options.data === 'string' || Object.prototype.toString.call(options.data) === '[object Object]')) {throw new Error('data需要一个字符串格式或者对象格式')}// 1-5.验证headers:要么不写,要么是对象格式if (!(options.headers === undefined || Object.prototype.toString.call(options.headers) === '[object Object]')) {throw new Error('headers需要一个对象格式')}// 1-6.验证dataType参数:要么不写,要么是string 或者 json if (!(options.dataType === undefined || /^(string|json)$/.test(options.dataType))) {throw new Error('dataType 只能写 string json')}// 2.准备一个默认值const _default = {// 修改请求地址:基准地址+options.url// eg:options.url = /test/firsturl: baseUrl + options.url,// method只有三个选择(没写,get,post)method: options.method || 'get',// async只有三个选择(没写,true,false)并且没写:默认值是true// 一个ES2020新的操作符 ??// ?? 空值运算符: 只有左边的是undefined或者null, 才使用右边的async: options.async ?? true,// data只能有三个选择:字符串、对象、undefined,默认值是''data: options.data || '',// headers只能是 undefined或者对象,默认是{'content-type': 'application/x-www-form-urlencoded'}headers: { 'content-type': 'application/x-www-form-urlencoded', ...options.headers },// 是否解析响应的参数 dataType, (选填) 默认是string,  (选填) jsondataType: options.dataType || 'string'}// 2-1.data可能是对象,如果是对象,需要转为查询字符串格式if (typeof _default.data === 'object') {_default.data = queryString(_default.data)}// 2-2.请求方式是get并且data有值,url需要拼接上刚刚转换的dataif (/^get$/i.test(_default.method) && _default.data) {_default.url = _default.url + '?' + _default.data}// 3 创建ajax对象 按照promise方式const p = new Promise(function (resolve, reject) {const xhr = new XMLHttpRequest()xhr.open(_default.method, _default.url, false)xhr.onload = function () {// 这里的xhr.readyState必然是4,onload是一个请求完成的事件// 如果请求成功,xhr状态码是4,http状态码是200-299 成功// 需求, 根据业务进一步封装,如果后端返回的内容中,code为1,成功,其他失败if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)) {let res = xhr.responseText// 根据服务端返回的内容判断// 首先代码进入到这里,http请求成功,可以成功从服务端拿到响应内容// 响应内容分两种情况,// 一个是正确的// 一个是业务错误 (参数不正确,代码错误,其他....)// 根据后端返回的内容判断, code:1 正确的 成功// code 不是1 错误(用户密码错误,登录时间过期 )try {res = JSON.parse(res)}catch (err) {return}if (res.code === 1) {// 正确的:成功返回正确的数据 resolve({ code: 1, message: "成功", data: _default.dataType === 'string' ? xhr.responseText : res })} else {// 错误:包括各种错误 resolve({ code: 0, message: '业务失败', err: res })}} else {// 请求不成功 -- 进入这里的代码必然是http状态码不是200-299的情况let res = xhr.responseTextresolve({ code: 0, message: '网络请求失败', err: res })}}// 如果post if (/^post$/i.test(_default.method)) {xhr.setRequestHeader('content-type', _default.headers['content-type'])}// 如果有token if (_default.headers.authorization) {xhr.setRequestHeader('authorization', _default.headers['authorization'])}// 如果是post 需要发送dataif (/^post$/i.test(_default.method)) {xhr.send(_default.data)} else {xhr.send()}})// 把promise对象返回return p}// 返回ajax函数return ajax
}
// 设置url基准地址
let ajax = createAjax('http://localhost:8888')

测试:

// 1.利用Promise的then()方法测试封装的ajax
// ajax({
//     url: '/test/first',
// }).then(res => {
//     console.log(res);
// })// 2.利用async await 测试封装的ajax
async function fn() {const res = await ajax({ url: '/goods/list', dataType: 'json' })console.log(res);
}
fn()

:测试前需要开启本地服务器

本地服务器下载地址:Ajax案例测试本地服务器-Node.js文档类资源-CSDN文库

五. async和await

  1. async其实就是promise的语法糖。函数前面加一个async,函数里面异步操作的方法前加一个await关键字。

    顾名思义,await就是让你等一下,执行完了再继续往下走。

    注意:await只能在async函数中执行,否则会报错。

    目的:让异步代码像同步代码一样执行。

  2. async:异步的意思,作用是申明一个异步函数,函数的返回值是promise 对象

    async function fn1() { }
    console.log(fn1()); //async函数隐式返回一个promise对象
    
  3. await:等待

    await是async+wait的结合 即异步等待,async和await 二者必须是结合着使用。

    :匿名函数也可以使用async和await

    !async function () {let h = await new Promise((resolve, reject) => {resolve('hello')});console.log(h); //hello  证明await就是promise里面then的语法糖。
    }();
    

结束语

希望对您有一点点帮助,如有错误欢迎小伙伴指正。
👍点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!💪💪💪

相关文章:

【ES6】掌握Promise和利用Promise封装ajax

&#x1f4bb; 【ES6】掌握Promise和利用Promise封装ajax &#x1f3e0;专栏&#xff1a;JavaScript &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向&#xff1a;目…...

REDIS-持久化方案

我们知道redis是内存数据库&#xff0c;它的数据是存储在内存中的&#xff0c;我们知道内存的一个特点是断电数据就丢失&#xff0c;所以redis提供了持久化功能&#xff0c;可以将内存中的数据状态存储到磁盘里面&#xff0c;避免数据丢失。 Redis持久化有三种方案&#xff0c;…...

五、Java框架之Maven进阶

黑马课程 文章目录1. 分模块开发1.1 分模块开发入门案例示例&#xff1a;抽取domain层示例&#xff1a;抽取dao层1.2 依赖管理2. 聚合和继承2.1 聚合概述聚合实现步骤2.2 继承 dependencyManagement3. 属性管理3.1 依赖版本属性管理3.2 配置文件属性管理&#xff08;了解&#…...

1.前言【Java面试第三季】

1.前言【Java面试第三季】前言推荐1.前言00_前言闲聊和课程说明本课程介绍目前考核的变化趋势vcr集数和坚持学长谷粉面试题复盘反馈最后前言 2023-2-1 12:30:05 以下内容源自 【尚硅谷Java大厂面试题第3季&#xff0c;跳槽必刷题目必扫技术盲点&#xff08;周阳主讲&#xff0…...

06分支限界法

文章目录八数码难题普通BFS算法全局择优算法&#xff08;A算法&#xff0c;启发式搜索算法&#xff09;单源最短路径问题装载问题算法思想&#xff1a;队列式分支限界法优先队列式分支限界法布线问题最大团问题批处理作业调度问题分支限界法与回溯法的区别&#xff1a; &#x…...

Docker Compose编排

一、概念1、Docker Compose是什么Docker Compose的前身是Fig&#xff0c;它是一个定义及运行多个Docker容器的工具通过 Compose&#xff0c;不需要使用shell脚本来启动容器&#xff0c;而使用 YAML 文件来配置应用程序需要的所有服务然后使用一个命令&#xff0c;根据 YAML 的文…...

Docker进阶 - 11. Docker Compose 编排服务

注&#xff1a;本文只对一些重要步骤和yml文件进行一些讲解&#xff0c;其他的具体程序没有记录。 目录 1. 原始的微服务工程编排(不使用Compose) 2. 使用Compose编排微服务 2.1 编写 docker-compose.yml 文件 2.2 修改并构建微服务工程镜像 2.3 启动 docker-compose 服务…...

福利篇2——嵌入式岗位笔试面试资料汇总(含大厂笔试面试真题)

前言 汇总嵌入式软件岗位笔试面试资料,供参考。 文章目录 前言一、公司嵌入式面经1、小米1)面试时长2)面试问题2、科大讯飞1)面试时长2)面试题目3、其余公司面经二、嵌入式笔试面试资料(全)三、嵌入式岗位薪资报告四、硬件岗位薪资报告一、公司嵌入式面经 1、小米 1)…...

[ubuntu]LVM磁盘管理

LVM是 Logical Volume Manager&#xff08;逻辑卷管理&#xff09;的简写&#xff0c;是Linux环境下对磁盘分区进行管理的一种机制&#xff0c;由Heinz Mauelshagen在Linux 2.4内核上实现。LVM可以实现用户在无需停机的情况下动态调整各个分区大小。1.简介 ​ LVM本质上是一个…...

开源流程引擎Camunda

开源流程引擎Camunda 文章作者&#xff1a;智星 1.简介 Camunda是一个轻量级的商业流程开源平台&#xff0c;是一种基于Java的框架&#xff0c;持久层采用Mybatis&#xff0c;可以内嵌集成到Java应用、SpringBooot应用中&#xff0c;也可以独立运行&#xff0c;其支持BPMN&a…...

【PTA Advanced】1155 Heap Paths(C++)

目录 题目 Input Specification: Output Specification: Sample Input 1: Sample Output 1: Sample Input 2: Sample Output 2: Sample Input 3: Sample Output 3: 思路 代码 题目 In computer science, a heap is a specialized tree-based data structure that s…...

Educational Codeforces Round 129 (Rated for Div. 2)

A. Game with Cards. 题目链接 题目大意&#xff1a; Alice和Bob玩卡牌。Alice有n张&#xff0c;Bob有m张。第一轮选手出一张数字卡牌。第二轮另一个选手要选择一张比他大的&#xff0c;依此类推。谁没有牌可出则输。问Alice和Bob分别先手时&#xff0c;谁赢&#xff1f;输出…...

[数据库]表的增删改查

●&#x1f9d1;个人主页:你帅你先说. ●&#x1f4c3;欢迎点赞&#x1f44d;关注&#x1f4a1;收藏&#x1f496; ●&#x1f4d6;既选择了远方&#xff0c;便只顾风雨兼程。 ●&#x1f91f;欢迎大家有问题随时私信我&#xff01; ●&#x1f9d0;版权&#xff1a;本文由[你帅…...

分享77个JS菜单导航,总有一款适合您

分享77个JS菜单导航&#xff0c;总有一款适合您 77个JS菜单导航下载链接&#xff1a;https://pan.baidu.com/s/1e_384_1KC2oSTDy7AaD3og?pwdzkw6 提取码&#xff1a;zkw6 Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj class ChinaZJsSeleni…...

kubernetes -- 核心组件介绍以及组件的运行流程

常用组件大白话说 如果想要官方的&#xff0c;详细的信息&#xff0c;请看官方文档。 https://kubernetes.io/zh-cn/docs/concepts/overview/components/ 现在介绍一些核心的概念&#xff1a; etcd&#xff1a;存储所有节点的信息&#xff0c;节点上部署的容器信息等都存在数…...

微信小程序Springboot短视频分享系统

3.1小程序端 用户注册页面&#xff0c;输入用户的个人信息点击注册即可。 注册完成后会返回到登录页面&#xff0c;用户输入自己注册的账号密码即可登录成功 登录成功后我们可以看到有相关的视频还有视频信息&#xff0c;我的信息等。 视频信息推荐是按照点击次数进行推荐的&am…...

排序算法学习

文章目录前言一、直接插入排序算法二、折半插入排序算法三、2路插入排序算法四、快速排序算法学习前言 算法是道路生涯的一个巨大阻碍。今日前来解决这其中之一&#xff1a;有关的排序算法&#xff0c;进行实现以及性能分析。 一、直接插入排序算法 插入排序算法实现主要思想…...

常见漏洞之 struts2+ jboss

数据来源 本文仅用于信息安全的学习&#xff0c;请遵守相关法律法规&#xff0c;严禁用于非法途径。若观众因此作出任何危害网络安全的行为&#xff0c;后果自负&#xff0c;与本人无关。 01 Struts2相关介绍 》Struts2概述 》Struts2历史漏洞&#xff08;1&#xff09; 》…...

leetcode470 用Rand7()实现Rand10()

力扣470 第一步&#xff1a;根据Rand7()函数制作一个可以随机等概率生成0和1的函数rand_0and1 调用Rand7()函数&#xff0c;随机等概率生成1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;7 这时我们设置&#xff1a;生成1&#xff0c;2&a…...

JSON数据解析商品详情API

大家有探讨稳定获取商品主图、jiage、标题&#xff0c;及sku的完整解决方案。这个引起了我技术挑战的兴趣&#xff0c;然后各种网上资料查询&#xff0c;最终还是不负努力&#xff0c;找到更好的解决方案&#xff0c;不再出现任何滑块验证码&#xff0c;完全绕过&#xff0c;实…...

服务端开发Java面试复盘篇1

上周投了一些简历&#xff0c;约了8-9家面试&#xff0c;其中完成了3家的第一轮面试&#xff0c;由于面试的是Java 的实习生&#xff0c;感觉问的题目都比较基础&#xff0c;不过有些问题回答的不是很好&#xff0c;在这里对回答的不太好的题目做一下总结和复盘。 目录 一、后…...

Android框架WiFi架构

同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 一、wpa_supplicant:wpa_supplicant本身开源项目源码,被谷歌收购之后加入Android移…...

rt-thread 移植调试记录

rt-thread 移植调试记录 记录rt-thread移植的过程。这里移植仅仅是利用rt-thread源码目录已经移植好的文件&#xff0c;组建自己的工程&#xff0c;不需要自己编写汇编完成底层移植。 1. 搭建基础工程 这里使用的是正点原子的潘多拉开发板&#xff0c;MCU为stm32l475。需要先…...

红外线额温枪与红外线温度传感器的原理分析

额温枪主要针对测量人体额温基准而设计&#xff0c;使用也非常简单方便。测体温可以达到一秒即可准确测量。并且不需要接触人体&#xff0c;隔着空气即可一键测温。非常适合家庭、学校、企业等场所。 但是由于其精度原因&#xff08;一般为 0.2 ℃&#xff0c;也有更低的&#…...

2023牛客寒假算法集训营4

目录A. [清楚姐姐学信息论](https://ac.nowcoder.com/acm/contest/46812/A)&#xff08;数学&#xff09;B. [清楚姐姐学构造](https://ac.nowcoder.com/acm/contest/46812/B)&#xff08;数学 构造&#xff09;C. [清楚姐姐学01背包(Easy Version)](https://ac.nowcoder.com/…...

vue组合式API及生命周期钩子函数

一、组合式API 什么是组合式API&#xff1f; vue3中支持vue2的选项式、支持新的编程模式–函数式编程&#xff08;没有this指针&#xff09;做了一个兼容&#xff0c;可以在一个组件中使用函数式编程和OOP编程&#xff08;选项式&#xff09; setup()函数 可以使用setup属性…...

Python|每日一练|数组|回溯|二分查找|排序和顺序统计量|.update方法 |单选记录:组合总和|寻找峰值|编程通过键盘输入每一位运动员

1、组合总和&#xff08;数组、回溯&#xff09; 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明&#xff1a; 所有数字&#xff08;包括 t…...

minio下载文件速度很慢的原因分析与说明

文章目录1.实战背景2.问题描述3.问题分析4.问题解决1.实战背景 最近在做一个项目&#xff0c;需要用到minio来搭建文件系统&#xff0c;先简单说一下我在项目中设置的上传文件流程&#xff1a; 前端将分块文件逐一传给后端&#xff0c;后端再存储到 linux服务器的minio 当中。…...

基于comsol软件弯曲单模光纤模拟仿真

在本节中&#xff0c;主要基于实验室实际光纤单模圆柱光纤进行模拟&#xff0c;与comsol案例库文件在分析过程和建模有些差异&#xff1a; 模拟主要通过以下三个步骤进行&#xff1a;模型的几何构建、物理场的添加研究、结构处理分析来进行。 下面是第一步骤&#xff1a;几何…...

如何开启多个独立Chrome浏览器

一、简介 作为测试或者开发人员&#xff0c;有些情况下会用到 Chrome 浏览器&#xff0c;但有时是同一个 Chrome 浏览器无法为我们提供隔离开的不同环境。这样 我们就需要清理 cache 、切换账号等&#xff0c;降低了我们的工作效率。今天的主题是如何开启多个独立的 Chrome 浏…...

网站设计做微信发现界面/网站域名服务器查询

random库是使用随机数的Python标准库 从概率论角度来说&#xff0c;随机数是随机产生的数据&#xff08;比如抛硬币&#xff09;&#xff0c;但时计算机是不可能产生随机值&#xff0c;真正的随机数也是在特定条件下产生的确定值&#xff0c;只不过这些条件我们没有理解&#x…...

为什么做腾讯网站/网页设计案例

Autowired注解Mapper报错问题描述解决方法问题描述 代码如下&#xff1a; Mapper类 Mapper public interface CategoryMapper { Select("select * from category_") List<Category> findAll();} 123456 Controller类 Controller public class CategoryContro…...

做动态网站的软件有哪些/搭建一个网站平台需要多少钱

centos7下使用pip7.1.0安装软件&#xff0c;在shell下设置了全局http_proxy和https_proxy&#xff0c;但是每次都遇到网络超时问题&#xff0c; 后来使用pip install xxx --proxy <proxy>&#xff0c;安装成功了。...

珠海百度seo公司/织梦seo排名优化教程

环广西公路自行车世界巡回赛是经国际自行车联合会授权的世界顶级赛事&#xff0c;也是中国唯一的公路自行车世界巡回赛。此前&#xff0c;北海已经成功举办了两届环广西公路自行车世界巡回赛北海赛段比赛&#xff0c;今年是世巡赛环广西的第三年。自2017年环广西公路自行车世界…...

怎么用dw制作网站/下载百度极速版免费安装

在我的一个网站上,我创建了一个表单,用于收集人员姓名,电子邮件和他们想法的描述.我将描述的字符限制为500个字符,因为我不想阅读,我想出了如何在用户输入他们想要的内容之前将文本显示在textarea中.目前用户必须自己删除“你的想法的描述”,但我想添加占位符类,当它们点击text…...

上海百度做网站/哪有学电脑培训班

苹果的Safari 浏览器默认情况下会开启欺诈性网址警告&#xff0c;该功能旨在帮助用户访问某些网站时检查提供安全建议。例如当用户访问的网站属于钓鱼网站会存在恶意内容&#xff0c;则欺诈性网址警告会立即弹出提示自动阻止用户继续访问。如何判断网站是否存在恶意内容或属于钓…...