Promise

Promise

什么是Promise

Promise是一种异步编程的解决方案,可以避免回调地狱,使得异步操作更加简单、清晰、灵活。

为什么使用Promise

function request(cb) {// 模拟网络请求let flag = Math.random() <= 0.5 ? true : falsesetTimeout(() => {cb(flag, flag ? '成功的数据' : '失败的信息')}, 1000)
}
request((status, msg) => {console.log(status, msg)
})

在这里如果需要在返回的方法里面再继续调用其他接口就会变成

request((s1, m1) => {request((s2, m2) => {request((s3, m3) => {// 出现了回调地狱}})
})

而 Promise 可以很好的解决异步操作的问题

const p = new Promise((resolve,reject)=>{setTimeout(()=>{resolve('123')},1000)
}).then(res=>{return new Promise(resolve=>resolve(res+'a'))
}).then(res=>{return new Promise(resolve=>resolve(res+'b'))
})
p.then(res=>{console.log(res)})

Promise 嵌套使用时,内层的 Promise 可以省略不写

const p = new Promise((resolve,reject)=>{setTimeout(()=>{resolve('123')},1000)
}).then(res=>{return res + 'a'
}).then(res=>{return res + 'b'
})
p.then(res=>{console.log(res)})

Promise的状态

Promise是一个状态机,分为 3 种状态:
当通过new创建Promise实例时,需要传入一个回调函数,我们称之为executor

1.pending:待定状态,执行了 executor 后,处于该状态
2.fulfilled:兑现状态,调用resolve()后,Promise 的状态更改为 fullfilled,且无法再次更改
3.rejected:拒绝状态,调用reject()后,Promise 的状态更改为 rejected,且无法再次更改

let p = new Promise((resolve, reject) => {// 这个时候是pending状态  待定状态if () { // 判断条件resolve()// 变为fulfilled状态  已执行状态} else {reject()// 变为rejected状态  已拒绝状态}
})

测试题

const promise1 = new Promise((resolve, reject) => {console.log('promise1')
})
console.log('1', promise1);
展开 从上至下,先遇到new Promise,执行该构造函数中的代码promise1 然后执行同步代码1,此时promise1没有被resolve或者reject,因此状态还是pending

在看这道题之前插入一下扩展的微任务和宏任务

const promise = new Promise((resolve, reject) => {console.log(1);resolve('success')  // 题目变形  如果这里去掉会是什么输出console.log(2);
});
promise.then(() => {console.log(3);
});
console.log(4);
展开 从上至下,先遇到new Promise,执行其中的同步代码1 再遇到resolve('success'), 将promise的状态改为了resolved并且将值保存下来 继续执行同步代码2 跳出promise,往下执行,碰到promise.then这个微任务,将其加入微任务队列 执行同步代码4 本轮宏任务全部执行完毕,检查微任务队列,发现promise.then这个微任务且状态为resolved,执行它。

Promise API

1个构造函数: new Promise
3个实例方法:.then 和 .catch .finally
6个静态方法:Promise.all、Promise.race、Promise.resolve、Promise.reject、Promise.allSettled、Promise.any

.then

const promise = new Promise(resolve => {resolve('1')
})
promise.then(res => console.log(res))
promise.then(res => console.log(res))//如果返回的是普通值,那么这个普通值将作为一个新的 Promise 的resolve的值
promise.then(() => 'then').then(res => console.log(res))
// promise.then(() => 'then') 相当于
promise.then(() => {return new Promise(resolve => {resolve('then')})
})
// 如果返回的是 Promise,那么就可以再次调用then方法
promise.then(() => {return new Promise(resolve => {setTimeout(() => {resolve('success')}, 2000)})}).then(msg => {// 2 秒后打印 successconsole.log(msg)})

测试题

const promise1 = new Promise((resolve, reject) => {console.log('promise1')resolve('resolve1')
})
const promise2 = promise1.then(res => {console.log(res)
})
console.log('1', promise1);
console.log('2', promise2);
展开 从上至下,先遇到new Promise,执行该构造函数中的代码promise1 碰到resolve函数, 将promise1的状态改变为resolved, 并将结果保存下来 碰到promise1.then这个微任务,将它放入微任务队列 promise2是一个新的状态为pending的Promise 执行同步代码1, 同时打印出promise1的状态是resolved 执行同步代码2,同时打印出promise2的状态是pending 宏任务执行完毕,查找微任务队列,发现promise1.then这个微任务且状态为resolved,执行它。

.catch

catch可以用来捕获reject错误

const promise = new Promise((resolve, reject) => {reject('error')
})promise.then(undefined, err => {// 打印 errorconsole.log(err)
})promise.then(() => {}).catch(err => {console.log(err)})// 虽然也可以使用promise.catch来处理  但是promise中的规范规定promise必须有.then

测试题

const promise = new Promise((resolve, reject) => {resolve("success1");reject("error");resolve("success2");
});
promise
.then(res => {console.log("then: ", res);}).catch(err => {console.log("catch: ", err);})
展开 构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用
Promise.resolve().then(() => {return new Error('error')//throw new Error('error')
}).then(res => {console.log("then: ", res)
}).catch(err => {console.log("catch: ", err)
})
展开 返回任意一个非 promise 的值都会被包裹成 promise 对象 因此这里的return new Error('error')也被包裹成了return Promise.resolve(new Error('error'))

finally

finally 是 ES9(ES2018) 新增的一个特性,finally 不接收参数
无论一个Promise实例是fulfilled或rejected,finally都会执行
finally可以用于处理无论是成功还是失败都要处理的事,比如说隐藏loading

const promise = new Promise((resolve, reject) => {reject('error')
})
promise.then(res => {console.log('res:', res)}).catch(err => {console.log(('err', err))}).finally(() => {console.log('finally')})

Promise.resolve

使用Promise.resolve()相当于new Promise(resolve => { resolve() })
resolve 参数形态:
参数本身是 Promise
参数是原始值/对象
参数是一个 thenable // thenable 是一个具有 then()功能 。 所有的 Promise 都是 thenable,但并不是所有的 thenable 都是 Promise

// 将一个现成的数据转换为一个 Promise 实例
const foo = {name: 'a',
}
function bar(obj) {return Promise.resolve(obj)
}
bar(foo).then(res => {console.log(res)
})

Promise.reject

与Promise.resolve()方法逻辑基本相同,只不过Promise.reject()相当于创建一个 Promise 实例,并且 rejected 了
与Promise.resolve()不同的是,Promise.reject()无论传递什么参数都会原样输出

Promise.all

只有全部为resolve才会调用 通常会用来处理 多个并行异步操作

  let p1 = new Promise(function(resolve, reject){setTimeout(()=>{resolve('123')},1000)})let p2 = new Promise(function(resolve, reject){setTimeout(()=>{resolve('456')},1000)})let p3 = new Promise(function(resolve, reject){setTimeout(()=>{reject('789')},1000)})let p = Promise.all([p1, p2, p3])p.then((res)=>{// 三个都成功则成功console.log(res,'都成功')}, (rej)=>{// 只要有失败,则失败console.log(rej,'至少有一个失败')})

allSettled

all方法是有缺陷的,如果在Promise队列中有一个状态是rejected,那么我们就无法获取到其他fullfilled以及pending的Promise实例了
allSettled是ES11(ES2020) 中新增的一个 API

  let p1 = new Promise(function(resolve, reject){resolve('success1')})let p2 = new Promise(function(resolve, reject){reject('error')})let p3 = new Promise(function(resolve, reject){resolve('success2')})let p = Promise.allSettled([p1, p2, p3])p.then((res)=>{console.log('res', res)})

Promise.race

有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现

let p1 = new Promise(function (resolve, reject) {setTimeout(resolve, 500, 'P1');
});
let p2 = new Promise(function (resolve, reject) {setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {console.log(result); // 'P1'
});

Promise.any

any 方法会等待一个fulfilled状态,才会决定返回 Promise 实例的状态
如果队列中所有的实例都是rejected状态,那也需要等到所有执行完毕后才会决定返回的 Promise 实例的状态

  let p1 = new Promise(function(resolve, reject){setTimeout(() => {resolve('success1')}, 1000)})let p2 = new Promise(function(resolve, reject){setTimeout(() => {reject('err')}, 1100)})let p3 = new Promise(function(resolve, reject){setTimeout(() => {resolve('success2')}, 1200)})Promise.any([p1,p2,p3]).then(res => {console.log('res', res)}).catch(err => { // 都没有fulfilled则进入这边console.log('err', err)})

实现一个简单的new Promise

首先Promise是一个类,所以我们先实现一个简单的类

class _Promise {constructor(executor) { // constructor 是一种用于创建和初始化class创建的对象的特殊方法。executor() // 立刻执行构造函数传入的代码}
}

其次Promise有三种状态

// Promise的三种状态
const STATUS_PENDING = 'pending'
const STATUS_FULFILLED = 'fulfilled'
const STATUS_REJECTED = 'rejected'class _Promise {constructor(executor = () => {}) {// 立即执行构造函数,并且状态变为 pendingthis.status = STATUS_PENDINGconst resolve = () => {// 执行 resolve 后,状态变为 fulfilledthis.status = STATUS_FULFILLED}const reject = () => {// 执行 reject 后,状态变为 rejectedthis.status = STATUS_REJECTED}// 传入的回调会有两个参数 resolve/rejectexecutor(resolve, reject)}
}

在执行 resolve、reject 后状态固化

const STATUS_PENDING = 'pending'
const STATUS_FULFILLED = 'fulfilled'
const STATUS_REJECTED = 'rejected'class _Promise {constructor(executor = () => {}) {this.status = STATUS_PENDINGconst resolve = () => {// 如果状态是 PENDING 时才会执行代码if (this.status === STATUS_PENDING) {this.status = STATUS_FULFILLED}}const reject = () => {// 如果状态是 PENDING 时才会执行代码if (this.status === STATUS_PENDING) {this.status = STATUS_REJECTED}}executor(resolve, reject)}
}

then 方法可以接收两个参数,可以处理 resolve 和 reject

const STATUS_PENDING = 'pending'
const STATUS_FULFILLED = 'fulfilled'
const STATUS_REJECTED = 'rejected'class _Promise {constructor(executor = () => {}) {this.status = STATUS_PENDINGthis.value = undefinedthis.reason = undefined// resolve 需要接收一个参数const resolve = value => {if (this.status === STATUS_PENDING) {this.status = STATUS_FULFILLED// 将接收的参数保存在 Promise 中this.value = value}}// reject 也可以接收一个参数const reject = reason => {if (this.status === STATUS_PENDING) {this.status = STATUS_REJECTEDthis.reason = reason}}executor(resolve, reject)}// 实例方法 thenthen(onFulfilled, onRejected) {if (onFulfilled) onFulfilled(this.value)if (onRejected) onRejected(this.reason)}
}

executor 可以是一个异步函数

const STATUS_PENDING = 'pending'
const STATUS_FULFILLED = 'fulfilled'
const STATUS_REJECTED = 'rejected'class _Promise {constructor(executor = () => {}) {this.status = STATUS_PENDINGthis.value = undefinedthis.reason = undefined// 因为可以执行多次 then,因此需要将所有的任务放在一个队列中this.resolveQueue = []this.rejectQueue = []const resolve = value => {if (this.status === STATUS_PENDING) {this.status = STATUS_FULFILLEDthis.value = value// 在 resolve 时执行 resolveQueue 所有的任务if (this.resolveQueue.length)this.resolveQueue.forEach(item => item(this.value))}}const reject = reason => {if (this.status === STATUS_PENDING) {this.status = STATUS_REJECTEDthis.reason = reason// 在 reject 时执行 rejectQueue 所有的任务if (this.rejectQueue.length)this.rejectQueue.forEach(item => item(this.reason))}}// try...catch 捕获一下错误try {executor(resolve, reject)} catch (error) {reject(error)}}then(onFulfilled, onRejected) {// 由于 executor 可能是一个异步函数,所以就不能直接来执行传入的参数了,需要做一下状态判断// 如果执行 then 时 Promise 实例的状态已经变化,那么就可以直接执行传入的参数if (this.status === STATUS_FULFILLED && onFulfilled) {onFulfilled(this.value)}if (this.status === STATUS_REJECTED && onRejected) {onRejected(this.reason)}// 如果在执行 then 的时候当前的状态还是 PENDING// 那么就加入队列中,等待执行 resolve、reject 的时候统一执行所有的队列if (this.status === STATUS_PENDING) {// 将任务放到相应队列中if (onFulfilled) this.resolveQueue.push(onFulfilled)if (onRejected) this.resolveQueue.push(onRejected)}}
}

实现链式调用

const STATUS_PENDING = 'pending'
const STATUS_FULFILLED = 'fulfilled'
const STATUS_REJECTED = 'rejected'class _Promise {constructor(executor = () => {}) { // constructor部分无改动this.status = STATUS_PENDINGthis.value = undefinedthis.reason = undefinedthis.resolveQueue = []this.rejectQueue = []const resolve = value => {if (this.status === STATUS_PENDING) {this.status = STATUS_FULFILLEDthis.value = valueif (this.resolveQueue.length)this.resolveQueue.forEach(item => item(this.value))}}const reject = reason => {if (this.status === STATUS_PENDING) {this.status = STATUS_REJECTEDthis.reason = reasonif (this.rejectQueue.length)this.rejectQueue.forEach(item => item(this.reason))}}try {executor(resolve, reject)} catch (error) {reject(error)}}then(onFulfilled, onRejected) {// 要想做到链式调用,就需要返回新的 Promisereturn new _Promise((resolve, reject) => {if (this.status === STATUS_FULFILLED && onFulfilled) {// 将 onFulfilled 返回的值作为下一个 Promise resolve() 的值const value = onFulfilled(this.value)resolve(value)}if (this.status === STATUS_REJECTED && onRejected) {// 这个也是同理const reason = onRejected(this.reason)resolve(reason)}if (this.status === STATUS_PENDING) {// 这里需要做一下处理了,因为这里队列是在构造函数中处理的// 所以需要转化一下if (onFulfilled)this.resolveQueue.push(param => {const value = onFulfilled(param)resolve(value)})if (onRejected)this.resolveQueue.push(param => {const reason = onRejected(param)resolve(reason)})}})}
}

catch捕获Promise实例的reject

const STATUS_PENDING = 'pending'
const STATUS_FULFILLED = 'fulfilled'
const STATUS_REJECTED = 'rejected'function executeFnWithCatchError(fn, param, resolve, reject) { // 用于try...catch...捕获错误try {const result = fn(param)resolve(result)} catch (error) {reject(error)}
}class _Promise {constructor(executor = () => {}) { // constructor部分无改动this.status = STATUS_PENDINGthis.value = undefinedthis.reason = undefinedthis.resolveQueue = []this.rejectQueue = []const resolve = value => {if (this.status === STATUS_PENDING) {this.status = STATUS_FULFILLEDthis.value = valueif (this.resolveQueue.length)this.resolveQueue.forEach(item => item(this.value))}}const reject = reason => {if (this.status === STATUS_PENDING) {this.status = STATUS_REJECTEDthis.reason = reasonif (this.rejectQueue.length)this.rejectQueue.forEach(item => item(this.reason))}}try {executor(resolve, reject)} catch (error) {reject(error)}}then(onFulfilled, onRejected) {onFulfilled = onFulfilled? onFulfilled: value => {return value}onRejected = onRejected? onRejected: reason => {throw new Error(reason)}return new _Promise((resolve, reject) => {if (this.status === STATUS_FULFILLED) {// 捕获错误executeFnWithCatchError(onFulfilled, this.value, resolve, reject)}if (this.status === STATUS_REJECTED) {// 捕获错误executeFnWithCatchError(onRejected, this.reason, resolve, reject)}if (this.status === STATUS_PENDING) {this.resolveQueue.push(param => {executeFnWithCatchError(onFulfilled, param, resolve, reject)})this.resolveQueue.push(param => {executeFnWithCatchError(onRejected, param, resolve, reject)})}})}catch(onRejected) {// 将传入的数据作为 then 的第二个参数this.then(undefined, onRejected)}all(promiseQueue) {return new _Promise((resolve, reject) => {const result = []// 对队列进行遍历promiseQueue.forEach(promise => {promise.then(res => {result.push(res)}).catch(err => {// 任何一个 reject 那么就直接 rejectreject(err)})})// 所有的 resolve,才 resolveresolve(result)})}
}

拓展 async/await

async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数

async function testAsync() {return "async";
}const result = testAsync();
console.log(result);// 输出的是一个 Promise 对象

await 也是一个修饰符,只能放在async定义的函数内。可以理解为等待
await 修饰的如果是Promise对象 可以获取Promise中返回的内容(resolve或reject的参数),且取到值后语句才会往下执行
如果不是Promise对象:把这个非promise的东西当做await表达式的结果

async function fun(){let a = await 1;let b = await new Promise((resolve,reject)=>{setTimeout(function(){resolve('setTimeout')},3000)})let c = await function(){return 'function'}()console.log(a,b,c)
}
fun();

拓展 微任务与宏任务

一开始整个脚本作为一个宏任务执行
执行过程中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列
当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完
执行浏览器UI线程的渲染工作
检查是否有Web Worker任务,有则执行
执行完本轮的宏任务,回到2,依此循环,直到宏任务和微任务队列都为空

微任务包括:MutationObserver、Promise.then()或catch()、Promise为基础开发的其它技术,比如fetch API、V8的垃圾回收过程、Node独有的process.nextTick。
宏任务包括:script 、setTimeout、setInterval 、setImmediate 、I/O 、UI rendering。

拓展 js的generator函数

Generator函数是ES6提供的一种异步编程解决方案
要创建一个 generator,我们需要一个特殊的语法结构:function*,即所谓的 “generator function”

function* generator() {yield '1'         // yield 表达式是暂停执行的标记return '2'
}
let iterator = generator()   // 调用 Generator函数,函数并没有执行,返回的是一个Iterator对象
iterator.next()            // {value: "1", done: false},value 表示返回值,done 表示遍历还没有结束
iterator.next()

上面的代码中可以看到传统函数和Generator函数的运行是完全不同的,传统函数调用后立即执行并输出了返回值;
Generator函数则没有执行而是返回一个Iterator对象,并通过调用Iterator对象的next方法来遍历
每次调用Iterator对象的next方法时,内部的指针就会从函数的头部或上一次停下来的地方开始执行
直到遇到下一个 yield 表达式或return语句暂停

promise async generator的差异

Promise,async/await和generator都是JavaScript中用来处理异步编程的方法。

Promise是一种用于处理异步操作的对象,它可以用于处理一次操作,当操作完成时会返回一个值。其优点是代码简单明了,易于理解和维护。

Async/await是Promise的一种语法糖,它可以让异步代码的写法更加清晰易懂。使用async/await,我们可以将异步操作的顺序代码化,就像使用同步方法一样。

Generator函数可以被理解为在函数执行的过程中可以挂起执行并在需要的时候恢复执行的一种语法。其特点是它返回一个迭代器对象,通过yield关键字可以在函数执行过程中暂停函数执行,同时保留函数执行时的上下文信息。这使得编写异步代码更加优雅。

总的来说,Promise更适用于一次性异步操作;async/await更适用于序列化异步操作并等待它们完成;Generator则更适用于需要控制异步操作的执行顺序。

参考地址

https://juejin.cn/post/7063377198014529572
https://juejin.cn/post/6844904063570542599
https://juejin.cn/post/6844903625769091079
https://juejin.cn/post/7011755708496478215
https://segmentfault.com/a/1190000007535316
https://juejin.cn/post/7062155174436929550
https://juejin.cn/post/6844904077537574919

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

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

相关文章

利用脚本将代码部署到测试环境(.sh)

1.将上次的部署文件备份名为xxx_bak 2.首次需要输入环境密码 3.并生成一个zip的压缩包,方便部署到线上环境 4.在终端 输入./update.sh 则可执行 文件名update.sh,放在package.json文件同级 # example: 1. ./update.sh 2. 输入服务器密码 【 如果不想每次都输入密码可以先生…

《零基础入门学习Python》第046讲:魔法方法:描述符(Property的原理)

0. 请写下这一节课你学习到的内容&#xff1a;格式不限&#xff0c;回忆并复述是加强记忆的好方式&#xff01; 常言道&#xff1a;“无规矩不成方圆”&#xff0c;讲的是万事万物的发展都要在一定的规则下去运行&#xff0c;只有遵循一定的协议去做&#xff0c;事情才能够按照…

k8s1.18.20:cert-manager 1.8 安装部署

cert-manager 安装部署 一、官网安装文档 https://cert-manager.io/docs/installation/ 1.1、简介 cert-manager 在 Kubernetes 集群中增加了证书 (certificates) 和证书颁发者 (certificate issuers) 作为资源类型&#xff0c;并简化了获取、更新和应用这些证书的过程。 …

基于 Orbit 的云原生应用交付基础原则与良好实践

点击官网了解详情 本文作者&#xff1a;何文强——腾讯云 CODING 高级架构师。 负责 CODING DevOps产品解决方案架构设计和技术产品布道以及 CODING 云原生技术研究与落地实践。在多个技术大会担任演讲嘉宾&#xff0c;腾讯云 CODING DevOps 课程认证出品人&#xff0c;腾讯云云…

PWM呼吸灯+流水灯设计

完成任务&#xff1a; 在流水灯基础上加入pwm呼吸灯设计&#xff0c;关于pwm呼吸灯设计可以看博主上一篇博客PWM呼吸灯设计 &#xff0c;开发板上灯每两秒进行一次切换&#xff0c;每一个的亮灭间隔为一秒。 代码参考&#xff1a; module pwm_led_change(input wire …

数据结构初阶--排序2

目录 前言快速排序思路hoare版本代码实现挖坑法代码实现前后指针法代码实现 快排优化三项取中法代码实现三指针代码实现 快排非递归代码实现 归并排序思路代码实现归并非递归代码实现 计数排序思路代码实现 前言 本篇文章将继续介绍快排&#xff0c;归并等排序算法以及其变式。…

antd-React Table 中文转化

1.首先需要进行中文包导入 2.引入标签对Table进行包裹即可 import zh_CN from antd/lib/locale-provider/zh_CN;import {ConfigProvider} from antd;<ConfigProvider locale{zh_CN}><Tablecolumns{columns}rowKey{record > record.id}dataSource{data}pagination{p…

【ArcGIS】shp导入报错ORA-00911无效字符

这个当个问题记录以下&#xff0c;就是shp文件名或者字段名有非正常字符&#xff0c;修改下名称重新导入即可&#xff1b; 直接改shp没法修改字段&#xff0c;会报错&#xff0c;需要先转化为gdb文件&#xff0c;然后在修改

算法篇--两数之和,梦开始的地方

目录 1.概念&#xff1a;2.两数之和&#xff08;1&#xff09;.暴力破解法&#xff08;2&#xff09;.使用哈希表 3.区别 1.概念&#xff1a; 非形式地说&#xff0c;算法(algorithm)就是任何良定义的计算过程&#xff0c;该过程取某个值或值的集合作为输入并产生某个值或值的集…

el-table组件插槽“slot-scope”

目录 一、代码展示 二、返回的数组对象不含value或者ispass&#xff0c;不会报错 三、插槽里面放的是要手动输入的值时 一、代码展示 <el-table v-loading"loading" :data"checklistList" selection-change"handleSelectionChange"><…

OV7670摄像头模块的使用

OV7670摄像头模块介绍 OV7670 CAMERACHIPTM 图像传感器&#xff0c;体积小、 工作电压低&#xff0c;提供单片 VGA 摄像头和影像处理器的所有功能。通过 SCCB 总线控制&#xff0c;可以输出整帧、子采样、取窗口等方式的各种分辨率 8 位影响数据。该产 品 VGA 图像最高达到 30…

Anaconda镜像源

Anaconda镜像源 清华镜像源阿里云镜像源中科大镜像源北大镜像源其他镜像源 清华镜像源 https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ # 清华大学Anaconda镜像使用帮助 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ # Anaconda安装包下载 https://mirro…

【Linux】内存使用相关

free 命令 查看内存大小 free -g :G单位 free -h : 可读性较高较理解 free -m : MB单位 total: 总内存used: 正在运行的进程使用的内存(used total – free – buff/cache)free: 未使用的内存 (free total – used – buff/cache)shared: 多个进程共享的内存buffers: 内存保留…

面试题更新之-伪元素和伪类

文章目录 伪元素和伪类是什么&#xff1f;伪元素&#xff08;Pseudo-elements&#xff09;:伪类&#xff08;Pseudo-classes&#xff09;: css伪元素和伪类的区别使用css伪元素的好处使用css伪类的好处 伪元素和伪类是什么&#xff1f; 在CSS中&#xff0c;伪元素&#xff08;…

xpath下载安装——Python爬虫xpath插件下载安装(2023.7亲测可用!!)

目录 1.免费下载插件链接&#xff08;若失效评论区留言发送最新链接&#xff09;&#xff08;2023.7亲测可用&#xff09; 2.安装插件 &#xff08;1&#xff09;打开chrome浏览器页面&#xff0c;点击&#xff1a;右上角三个点 > 扩展程序 > 管理拓展程序 &#xff…

MongoDB(MongoTemplate和MongoRepository)对比

目录 MongoTemplateMongoRepository MongoTemplate //条件查询GetMapping("findUser")public void findUserList() {Query query new Query(Criteria.where("name").is("zhang3").and("age").is(33));List<User> users mongoT…

gitbash2.41安装教程——2023.07

文章目录 1、下载安装包2、安装 1、下载安装包 进入官网下载&#xff0c;官网链接 上面有多种系统可以选择&#xff0c;我是windows&#xff0c;点击windows进行下载 这里可以直接下载最新版本的git 2.41.0 64位。 下载可能有点慢&#xff0c;耐心等待。 2、安装 下载完…

Hive基本操作

基本概念 Hive是基于Hadoop的一个【数据仓库工具】&#xff0c;可以将结构化和半结构化的数据文件映射为一张数据库表&#xff0c;并提供简单的sql查询功能。 介绍 Hive本质是将SQL转换为MapReduce的任务进行运算&#xff0c;底层由HDFS来提供数据存储&#xff0c;简单来说H…

JVM——类加载和垃圾回收

目录 前言 JVM简介 JVM内存区域划分 JVM的类加载机制 1.加载 双亲委派模型 2.验证 验证选项 3.准备 4.解析 5.初始化 触发类加载 JVM的垃圾回收策略 GC 一&#xff1a;找 谁是垃圾 1.引用计数 2.可达性分析 &#xff08;这个方案是Java采取的方案&#x…

基于单片机智能台灯坐姿矫正器视力保护器的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前当前光线强度、台灯灯光强度、当前时间、坐姿距离等&#xff1b;按键设置当前时间&#xff0c;闹钟、提醒时间、坐姿最小距离&#xff1b;通过超声波检测坐姿&#xff0c;当坐姿不正容易对眼睛和身体腰部等造成…