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

手写promise A+、catch、finally、all、allsettled、any、race

目录

手写promise

同步版

1.Promise的构造方法接收一个executor(),在new Promise()时就立刻执行executor回调

2.executor()内部的异步任务被放入宏/微任务队列,等待执行

3.状态与结果的管理

状态只能变更一次

4.then()调用成功/失败回调

catch是调用失败回调的简写

异步版

1.缓存成功与失败回调

2.then 增加 Pending处理

3.resolve 与 reject 中调用回调函数

多次调用同一个promise的then

1.缓存成功与失败回调 队列

2.pengding时,then()收集依赖,将成功/失败回调放入成功/失败队列

3.触发resolve/reject,从成功/失败队列中取出回调依次执行

then链式调用:返回一个 Promise 对象

then返回自己时,抛错循环调用

等返回的promise初始化好:queueMicrotask微任务

捕获错误

executor错误

then错误

then([onFulfilled, onRejected])参数可选

then 穿透:忽略非函数参数,非函数会同步执行

静态调用resolve、reject

完整版

Promise A+ 规范版的resolvePromise

catch

finally

并发请求

模板

all

allSettled

any

race


手写promise

同步版

1.将promise的resolve和reject函数传给实例用

 constructor(executor){// executor 是一个执行器,进入会立即执行// 并传入resolve和reject方法executor(this.resolve, this.reject) }

2.实例给resolve和reject函数传值

resolve('success')
reject('err')
// 新建 test.js// 引入我们的 MyPromise.js
const MyPromise = require('./MyPromise')
const promise = new MyPromise((resolve, reject) => {resolve('success')reject('err')
})promise.then(value => {console.log('resolve', value)
}, reason => {console.log('reject', reason)
})// 执行结果:resolve success

1.Promise的构造方法接收一个executor(),在new Promise()时就立刻执行executor回调

class Promise{// 构造方法接收一个回调constructor(executor){executor();}

2.executor()内部的异步任务被放入宏/微任务队列,等待执行

  // resolve和reject为什么要用箭头函数?
  // 如果直接调用的话,普通函数this指向的是window或者undefined
  // 用箭头函数就可以让this指向当前实例对象

class MyPromise {constructor(executor){// executor 是一个执行器,进入会立即执行// 并传入resolve和reject方法executor(this.resolve, this.reject) }// 更改成功后的状态resolve = () => {}// 更改失败后的状态reject = () => {}
}

3.状态与结果的管理

状态只能变更一次
// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';// 新建 MyPromise 类
class MyPromise {constructor(executor){...}// 储存状态的变量,初始值是 pendingstatus = PENDING;// 成功之后的值value = null;// 失败之后的原因reason = null;// 更改成功后的状态resolve = (value) => {// 只有状态是等待,才执行状态修改if (this.status === PENDING) {// 状态修改为成功this.status = FULFILLED;// 保存成功之后的值this.value = value;}}// 更改失败后的状态reject = (reason) => {// 只有状态是等待,才执行状态修改if (this.status === PENDING) {// 状态成功为失败this.status = REJECTED;// 保存失败后的原因this.reason = reason;}}
}

4.then()调用成功/失败回调

catch调用失败回调的简写
// MyPromise.jsthen(onFulfilled, onRejected) {// 判断状态if (this.status === FULFILLED) {// 调用成功回调,并且把值返回onFulfilled(this.value);} else if (this.status === REJECTED) {// 调用失败回调,并且把原因返回onRejected(this.reason);}
}

异步版

// test.jsconst MyPromise = require('./MyPromise')
const promise = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success')}, 2000); 
})promise.then(value => {console.log('resolve', value)
}, reason => {console.log('reject', reason)
})// 同步版没有打印信息(执行到then时,状态还是pending)
// 异步版等待 2s 输出 resolve success

1.缓存成功与失败回调

// MyPromise 类中新增
// 存储成功回调函数
onFulfilledCallback = null;
// 存储失败回调函数
onRejectedCallback = null;

2.then 增加 Pending处理

// MyPromise.jsthen(onFulfilled, onRejected) {...if (this.status === PENDING) {// ==== 新增 ====// 因为不知道后面状态的变化情况,所以将成功回调和失败回调存储起来// 等到执行成功失败函数的时候再传递this.onFulfilledCallback = onFulfilled;this.onRejectedCallback = onRejected;}
}

3.resolve 与 reject 中调用回调函数

// MyPromise.js// 更改成功后的状态
resolve = (value) => {// 只有状态是等待,才执行状态修改if (this.status === PENDING) {// 状态修改为成功this.status = FULFILLED;// 保存成功之后的值this.value = value;// ==== 新增 ====// 判断成功回调是否存在,如果存在就调用this.onFulfilledCallback && this.onFulfilledCallback(value);}
}

多次调用同一个promise的then

// test.jsconst MyPromise = require('./MyPromise')
const promise = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success')}, 2000); 
})promise.then(value => {console.log(1)console.log('resolve', value)
})promise.then(value => {console.log(2)console.log('resolve', value)
})promise.then(value => {console.log(3)console.log('resolve', value)
})
//单个回调:3
resolve success
//回调队列:
1
resolve success
2
resolve success
3
resolve success

1.缓存成功与失败回调 队列

// MyPromise.js// 存储成功回调函数
// onFulfilledCallback = null;
onFulfilledCallbacks = [];
// 存储失败回调函数
// onRejectedCallback = null;
onRejectedCallbacks = [];

2.pengding时,then()收集依赖,将成功/失败回调放入成功/失败队列

// MyPromise.jsthen(onFulfilled, onRejected) {// 判断状态if (this.status === FULFILLED) {// 调用成功回调,并且把值返回onFulfilled(this.value);} else if (this.status === REJECTED) {// 调用失败回调,并且把原因返回onRejected(this.reason);} else if (this.status === PENDING) {// ==== 新增 ====// 因为不知道后面状态的变化,这里先将成功回调和失败回调存储起来// 等待后续调用this.onFulfilledCallbacks.push(onFulfilled);this.onRejectedCallbacks.push(onRejected);}
}

3.触发resolve/reject,从成功/失败队列中取出回调依次执行

// MyPromise.js// 更改成功后的状态
resolve = (value) => {// 只有状态是等待,才执行状态修改if (this.status === PENDING) {// 状态修改为成功this.status = FULFILLED;// 保存成功之后的值this.value = value;// ==== 新增 ====// resolve里面将所有成功的回调拿出来执行while (this.onFulfilledCallbacks.length) {// Array.shift() 取出数组第一个元素,然后()调用,shift不是纯函数,取出后,数组将失去该元素,直到数组为空this.onFulfilledCallbacks.shift()(value)}}
}

then链式调用:返回一个 Promise 对象

以fulfilled为例,其他同理

// MyPromise.jsclass MyPromise {...then(onFulfilled, onRejected) {// 为了链式调用这里直接创建一个 MyPromise,并在后面 return 出去const promise2 = new MyPromise((resolve, reject) => {// 这里的内容在执行器中,会立即执行if (this.status === FULFILLED) {// 获取成功回调函数的执行结果const x = onFulfilled(this.value);// 传入 resolvePromise 集中处理resolvePromise(x, resolve, reject);} ...}) return promise2;}
}function resolvePromise(x, resolve, reject) {// 判断x是不是 MyPromise 实例对象if(x instanceof MyPromise) {// 执行 x,调用 then 方法,目的是将其状态变为 fulfilled 或者 rejected// x.then(value => resolve(value), reason => reject(reason))// 简化之后x.then(resolve, reject)} else{// 普通值resolve(x)}
}

then返回自己时,抛错循环调用

// test.jsconst promise = new Promise((resolve, reject) => {resolve(100)
})
const p1 = promise.then(value => {console.log(value)return p1
})

function resolvePromise(promise2, x, resolve, reject) {// 如果相等了,说明return的是自己,抛出类型错误并返回if (promise2 === x) {return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))}...
}
等返回的promise初始化好:queueMicrotask微任务

// MyPromise.jsclass MyPromise {......then(onFulfilled, onRejected) {const promise2 = new MyPromise((resolve, reject) => {if (this.status === FULFILLED) {// 创建一个微任务等待 promise2 完成初始化queueMicrotask(() => {// 获取成功回调函数的执行结果const x = onFulfilled(this.value);// 传入 resolvePromise 集中处理resolvePromise(promise2, x, resolve, reject);})  } ...}) return promise2;}
}

捕获错误

 try {异步操作
} catch (error) {reject(error)
}  

executor错误

// MyPromise.jsconstructor(executor){// ==== 新增 ====// executor 是一个执行器,进入会立即执行// 并传入resolve和reject方法try {executor(this.resolve, this.reject)} catch (error) {// 如果有错误,就直接执行 rejectthis.reject(error)}
}

then错误

// MyPromise.jsthen(onFulfilled, onRejected) {// 为了链式调用这里直接创建一个 MyPromise,并在后面 return 出去const promise2 = new MyPromise((resolve, reject) => {// 判断状态if (this.status === FULFILLED) {// 创建一个微任务等待 promise2 完成初始化queueMicrotask(() => {try {// 获取成功回调函数的执行结果const x = onFulfilled(this.value);// 传入 resolvePromise 集中处理resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error)}  })  } ...}) return promise2;
}

then([onFulfilled, onRejected])参数可选

then 穿透:忽略非函数参数,非函数会同步执行

Promise.resolve(1).then(2)//传入值.then(Promise.resolve(3))//传入promise对象.then(console.log)//传入函数
1

Promise.resolve().then(new Promise(r => {setTimeout(() => {r(console.log(1))}, 1000)})).then(new Promise(r => {setTimeout(() => {r(console.log(2))}, 1000)})).then(new Promise(r => {setTimeout(() => {r(console.log(3))}, 1000)}))
延迟1秒后,打印123

不同于下面

// MyPromise.jsthen(onFulfilled, onRejected) {// 如果不传,就使用默认函数onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason};// 为了链式调用这里直接创建一个 MyPromise,并在后面 return 出去const promise2 = new MyPromise((resolve, reject) => {......
}

静态调用resolve、reject

// MyPromise.jsMyPromise {......// resolve 静态方法static resolve (parameter) {// 如果传入 MyPromise 就直接返回if (parameter instanceof MyPromise) {return parameter;}// 转成常规方式return new MyPromise(resolve =>  {resolve(parameter);});}// reject 静态方法static reject (reason) {return new MyPromise((resolve, reject) => {reject(reason);});}
}

完整版

// MyPromise.js// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';// 新建 MyPromise 类
class MyPromise {constructor(executor){// executor 是一个执行器,进入会立即执行// 并传入resolve和reject方法try {executor(this.resolve, this.reject)} catch (error) {this.reject(error)}}// 储存状态的变量,初始值是 pendingstatus = PENDING;// 成功之后的值value = null;// 失败之后的原因reason = null;// 存储成功回调函数onFulfilledCallbacks = [];// 存储失败回调函数onRejectedCallbacks = [];// 更改成功后的状态resolve = (value) => {// 只有状态是等待,才执行状态修改if (this.status === PENDING) {// 状态修改为成功this.status = FULFILLED;// 保存成功之后的值this.value = value;// resolve里面将所有成功的回调拿出来执行while (this.onFulfilledCallbacks.length) {// Array.shift() 取出数组第一个元素,然后()调用,shift不是纯函数,取出后,数组将失去该元素,直到数组为空this.onFulfilledCallbacks.shift()(value)}}}// 更改失败后的状态reject = (reason) => {// 只有状态是等待,才执行状态修改if (this.status === PENDING) {// 状态成功为失败this.status = REJECTED;// 保存失败后的原因this.reason = reason;// resolve里面将所有失败的回调拿出来执行while (this.onRejectedCallbacks.length) {this.onRejectedCallbacks.shift()(reason)}}}then(onFulfilled, onRejected) {const realOnFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;const realOnRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason};// 为了链式调用这里直接创建一个 MyPromise,并在后面 return 出去const promise2 = new MyPromise((resolve, reject) => {const fulfilledMicrotask = () =>  {// 创建一个微任务等待 promise2 完成初始化queueMicrotask(() => {try {// 获取成功回调函数的执行结果const x = realOnFulfilled(this.value);// 传入 resolvePromise 集中处理resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error)} })  }const rejectedMicrotask = () => { // 创建一个微任务等待 promise2 完成初始化queueMicrotask(() => {try {// 调用失败回调,并且把原因返回const x = realOnRejected(this.reason);// 传入 resolvePromise 集中处理resolvePromise(promise2, x, resolve, reject);} catch (error) {reject(error)} }) }// 判断状态if (this.status === FULFILLED) {fulfilledMicrotask() } else if (this.status === REJECTED) { rejectedMicrotask()} else if (this.status === PENDING) {// 等待// 因为不知道后面状态的变化情况,所以将成功回调和失败回调存储起来// 等到执行成功失败函数的时候再传递this.onFulfilledCallbacks.push(fulfilledMicrotask);this.onRejectedCallbacks.push(rejectedMicrotask);}}) return promise2;}// resolve 静态方法static resolve (parameter) {// 如果传入 MyPromise 就直接返回if (parameter instanceof MyPromise) {return parameter;}// 转成常规方式return new MyPromise(resolve =>  {resolve(parameter);});}// reject 静态方法static reject (reason) {return new MyPromise((resolve, reject) => {reject(reason);});}
}function resolvePromise(promise2, x, resolve, reject) {// 如果相等了,说明return的是自己,抛出类型错误并返回if (promise2 === x) {return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))}// 判断x是不是 MyPromise 实例对象if(x instanceof MyPromise) {// 执行 x,调用 then 方法,目的是将其状态变为 fulfilled 或者 rejected// x.then(value => resolve(value), reason => reject(reason))// 简化之后x.then(resolve, reject)} else{// 普通值resolve(x)}
}module.exports = MyPromise;

Promise A+ 规范版的resolvePromise

要求判断 x 是否为 object 或者 function,满足则接着判断 x.then 是否存在,这里可以理解为判断 x 是否为 promise,这里都功能实际与我们手写版本中 x instanceof MyPromise 功能相似

// MyPromise.jsfunction resolvePromise(promise, x, resolve, reject) {// 如果相等了,说明return的是自己,抛出类型错误并返回if (promise === x) {return reject(new TypeError('The promise and the return value are the same'));}if (typeof x === 'object' || typeof x === 'function') {// x 为 null 直接返回,走后面的逻辑会报错if (x === null) {return resolve(x);}let then;try {// 把 x.then 赋值给 then then = x.then;} catch (error) {// 如果取 x.then 的值时抛出错误 error ,则以 error 为据因拒绝 promisereturn reject(error);}// 如果 then 是函数if (typeof then === 'function') {let called = false;try {then.call(x, // this 指向 x// 如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)y => {// 如果 resolvePromise 和 rejectPromise 均被调用,// 或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用// 实现这条需要前面加一个变量 calledif (called) return;called = true;resolvePromise(promise, y, resolve, reject);},// 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promiser => {if (called) return;called = true;reject(r);});} catch (error) {// 如果调用 then 方法抛出了异常 error:// 如果 resolvePromise 或 rejectPromise 已经被调用,直接返回if (called) return;// 否则以 error 为据因拒绝 promisereject(error);}} else {// 如果 then 不是函数,以 x 为参数执行 promiseresolve(x);}} else {// 如果 x 不为对象或者函数,以 x 为参数执行 promiseresolve(x);}
}

catch

//catch方法其实就是执行一下then的第二个回调
catch(rejectFn) {return this.then(undefined, rejectFn)
}

finally

由于无法知道promise的最终状态,所以finally的回调函数中不接收任何参数,它仅用于无论最终结果如何都要执行的情况

 finally(callBack) {return this.then(callBack, callBack)}

并发请求

模板

  /*** @param {iterable} promises 一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入* @returns */
static 并发(promises) {
// 参数校验
if (Array.isArray(promises)) {let result = []; // 存储结果let count = 0; // 计数器if (promises.length === 0) {
// 如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promisereturn resolve(promises);//C. 返回一个 已失败(already rejected) 状态的 Promise。return reject(new AggregateError('All promises were rejected'));}return new myPromise((resolve, reject) => {promises.forEach((item, index) => {myPromise.resolve(item).then(value => {count++;// 每个promise执行的结果存储在result中//A.记录所有reject/fulfilled,需要区分状态result[index] = {status: 'fulfilled',value}//B.只记录fulfilledresult[index] = value// 如果所有的 Promise 都已经处理完毕,就调用 resolve(result)count === promises.length && resolve(result);//C.只要一个成功resolve(value);},reason => {//A.记录所有rejectcount++;result[index] = {status: 'rejected',reason}count === promises.length && resolve(result);//B.一旦rejectreject(reason);     //C.全rejectcount++;errors.push(reason);//AggregateError是 Error 的一个子类,用于把单一的错误集合在一起。count === promises.length && reject(new AggregateError(errors));})})} else {return reject(new TypeError('Argument is not iterable'))
}}

all

/**
* 如果传入的 promise 中有一个失败(rejected),
* Promise.all 异步地将失败的那个结果给失败状态的回调函数,而不管其它 promise 是否完成
*/     
static all(promises) {
return new myPromise((resolve, reject) => {promises.forEach((item, index) => {myPromise.resolve(item).then(value => {count++;// 每个promise执行的结果存储在result中result[index] = value;// 如果所有的 Promise 都已经处理完毕,就调用 resolve(result)count === promises.length && resolve(result);},reason => {reject(reason);                         })})
}

allSettled

static allSettled(promises) {
return new myPromise((resolve, reject) => {promises.forEach((item, index) => {myPromise.resolve(item).then(value => {count++;// 每个promise执行的结果存储在result中//A.记录所有reject/fulfilled,需要区分状态result[index] = {status: 'fulfilled',value}// 如果所有的 Promise 都已经处理完毕,就调用 resolve(result)count === promises.length && resolve(result);},reason => {//A.记录所有rejectcount++;result[index] = {status: 'rejected',reason}count === promises.length && resolve(result);           })})
}

any

static any(promises){return new myPromise((resolve, reject) => {promises.forEach((item, index) => {myPromise.resolve(item).then(value => {//C.只要一个成功resolve(value);},reason => {//C.全rejectcount++;errors.push(reason);//AggregateError是 Error 的一个子类,用于把单一的错误集合在一起。count === promises.length && reject(new AggregateError(errors));})})
}

race

//race方法(返回最早执行完的promise结果,无论成功与否)
Promise.race = function(promises){return new myPromise((resolve, reject) => {// 如果传入的迭代promises是空的,则返回的 promise 将永远等待。if (promises.length > 0) {promises.forEach(item => {myPromise.resolve(item).then(resolve, reject);})}}})

手写实现 Promise 全部实例方法和静态方法,来看看 Promise.all、Promise.race 和 Promise.any 都是怎么实现的 - 掘金

从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节 - 掘金

相关文章:

手写promise A+、catch、finally、all、allsettled、any、race

目录 手写promise 同步版 1.Promise的构造方法接收一个executor()&#xff0c;在new Promise()时就立刻执行executor回调 2.executor()内部的异步任务被放入宏/微任务队列&#xff0c;等待执行 3.状态与结果的管理 状态只能变更一次 4.then()调用成功/失败回调 catch是…...

【原神游戏开发日志1】缘起

【原神游戏开发日志1】缘起 版权声明 本文为“优梦创客”原创文章&#xff0c;您可以自由转载&#xff0c;但必须加入完整的版权声明 文章内容不得删减、修改、演绎 相关学习资源见文末 大家好&#xff0c;最近看到原神在TGA上频频获奖&#xff0c;作为一个14年经验的游戏开…...

leetcode5 最长公共前缀三种python解法

14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"示…...

对小程序的初了解

WXML和HTML的区别 标签名称不同 HTML&#xff1a;div、a、span、img WXML&#xff1a;view、text、image、navigator 属性节点不同 <a href"#">超链接</a> <navigator url"/pages/home/home"></navigator> 提供了类似vue的…...

QLineEdit 的 InputMask掩码

QLineEdit 的 InputMask掩码 A&#xff1a;只能输入字母&#xff0c;且不可省略 a&#xff1a;只能输入字母&#xff0c;可以省略 N&#xff1a;只能输入 字母和数字&#xff0c;且不可省略 n&#xff1a;只能输入 字母和数字&#xff0c;可以省略 X&#xff1a;可以输入任意字…...

关于队列的简单理解

1.队列(Queue) 1.1 关于队列 队列 &#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c; 队列具有先进先出 FIFO(First In First Out)的操作特性&#xff08;队列是个接口&#xff09;&#xff1b; 入队列&#x…...

加密市场进入牛初阶段?一场新的造富效应即将拉开帷幕!

周一(12月4日)&#xff0c;比特币一度上涨至42000美元&#xff0c;创下自2022年4月以来的最高水平。从目前比特币的走势来看&#xff0c;加密市场无疑已然进入到牛初阶段。 在牛市初期&#xff0c;确实存在人们不相信牛市到来的情况。由于在熊市中亏损的心理阻碍和对市场进一步…...

Superset基础入门

1 Superset概述 Apache Superset 是一个现代的数据探索和可视化平台。它功能强大且十分易用&#xff0c;可对接 各种数据源&#xff0c;包括很多现代的大数据分析引擎&#xff0c;拥有丰富的图表展示形式&#xff0c;并且支持自定义 仪表盘。 2 Superset安装 Superset 是由 P…...

【泛微ecology】将多个字段的数据合并到一个字段

doFieldSQL("select concat(concat(sqr,,),sy) as c from formtable_main_2 where requestid $requestid$ ")...

WebSocket入门介绍及编程实战

HTTP的限制 全双工和半双工&#xff1a; 全双工&#xff1a;全双工&#xff08;Full Duplex&#xff09;是允许数据在两个方向上同时传输。 半双工&#xff1a;半双工&#xff08;Half Duplex&#xff09;是允许数据在两个方向上传输&#xff0c;但是同一个时间段内只允许一个…...

vue3里面生命周期的使用

前言&#xff1a; vue2里面的生命周期和vue3生命周期是非常的相似的&#xff0c;我们通过访问生命周期钩子来处理不同场景之间的应用。 生命周期钩子的函数定义&#xff1a;每一个Vue组件实例在创建时都需要经历一系列的初始化步骤&#xff0c;比如数据侦听&#xff0c;编译模…...

在python的Scikit-learn库中,可以使用train_test_split函数来划分训练集和测试集。

文章目录 一、在Scikit-learn库中&#xff0c;可以使用train_test_split函数来划分训练集和测试集总结 一、在Scikit-learn库中&#xff0c;可以使用train_test_split函数来划分训练集和测试集 在Scikit-learn库中&#xff0c;可以使用train_test_split函数来划分训练集和测试…...

外包干了2个月,技术明显退步了...

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近5年的功能测试&#xff0c;今年11月份&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…...

数据结构:链表应用:第9关:删除链表中满足区间值的结点

任务描述编程要求 输入输出测试说明来源 任务描述 本关任务&#xff1a;利用单链表表示一个递增的整数序列&#xff0c;删除链表中值大于等于mink且小于等于maxk的所有元素&#xff08;mink和maxk是给定的两个参数&#xff0c;其值可以和表中的元素相同&#xff0c;也可以不同…...

了解 ignore_above 参数对 Elasticsearch 中磁盘使用的影响

在 Elasticsearch 中&#xff0c;ignore_above 参数允许你忽略&#xff08;而不是索引&#xff09;长于指定长度的字符串。 这对于限制字段的大小以避免性能问题很有用。 在本文中&#xff0c;我们将探讨 “ignore_above” 参数如何影响 Elasticsearch 中字段的大小&#xff0c…...

C#中的async/await异步编程模型

前言 当谈到异步编程时&#xff0c;C#中的async/await是一个强大且方便的工具。它使得编写并发和异步操作变得更加简单和可读&#xff0c;同时提供良好的可维护性。本文将详细解释async/await的使用&#xff0c;以及如何在C#中有效地利用它来实现异步操作。 目录 前言1. async…...

【原创】提升MybatisPlus分页便捷性,制作一个属于自己的分页插件,让代码更加优雅

前言 MybatisPlus的分页插件有一点非常不好&#xff0c;就是要传入一个IPage&#xff0c;别看这个IPage没什么大不了的&#xff0c;最多多写一两行代码&#xff0c;可这带来一个问题&#xff0c;即使用xml的查询没法直接取对象里面变量的值了&#xff0c;得Param指定xml中的变…...

pythonselenium自动化测试实战项目

说明&#xff1a;本项目采用流程控制思想&#xff0c;未引用unittest&pytest等单元测试框架 一.项目介绍 目的 测试某官方网站登录功能模块可以正常使用 用例 1.输入格式正确的用户名和正确的密码&#xff0c;验证是否登录成功&#xff1b; 2.输入格式正确的用户名和不…...

智能优化算法应用:基于瞬态优化算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于瞬态优化算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于瞬态优化算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.瞬态优化算法4.实验参数设定5.算法结果6.参考…...

springMVC 三大组件解析

springMVC组件概述 DispatcherServlet&#xff08;调度器Servlet&#xff09;&#xff1a; DispatcherServlet 是 Spring MVC 的前端控制器&#xff08;Front Controller&#xff09;。它负责接收来自客户端的请求&#xff0c;然后将请求分发给相应的处理器&#xff08;Control…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

无需布线的革命:电力载波技术赋能楼宇自控系统-亚川科技

无需布线的革命&#xff1a;电力载波技术赋能楼宇自控系统 在楼宇自动化领域&#xff0c;传统控制系统依赖复杂的专用通信线路&#xff0c;不仅施工成本高昂&#xff0c;后期维护和扩展也极为不便。电力载波技术&#xff08;PLC&#xff09;的突破性应用&#xff0c;彻底改变了…...