从0开始实现es6 promise类

主要由基础实现和静态类的实现两部分组成。

1 基础实现(不含静态类)

 1.1 使用类实现完成构造函数

        实现代码如下,构造函数传入一个回调函数,定义resolve和reject函数,将两个函数作为参数执行回调函数。

// 1. 使用类实现,完成构造函数
class MyGoPromise{constructor(callback){const resolve = (result) => {console.log(result)}const reject = (result) => {console.log(result)}callback(resolve, reject)}
}

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {resolve("success")// reject("fail")
})

 1.2 实现状态(pending fulfilled rejected)及结果

        首先状态在类内直接声明默认值,状态固定为三个,声明为类外的字符串常量使用。实现在reject和resolve调用时候的状态变化(pending -> fulfilled, pending --> rejected)以及结果保存。代码实现如下所示:

// 2. 状态及原因 state(pending fulfilled rejected) result
// 常量最好单独定义,方便维护
const PENDING = "pending"
const FULFILLED = "fulfilled"
const REJECTED = "rejected"
class MyGoPromise{state = PENDINGresult = undefinedconstructor(callback){const resolve = (result) => {// 状态只能从pending变为fulfilled或者rejectedif(this.state === PENDING){this.state = FULFILLEDthis.result = result}}const reject = (result) => {if(this.state === PENDING){this.state = REJECTEDthis.result = result}}callback(resolve, reject)}
}

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {resolve("success")// reject("fail")
})
console.log(p)

 1.3 then的基础实现

  1.3.1 then的成功以及失败回调实现(同步)

        then接收两个回调函数,成功回调以及失败的回调,通过查阅文档得知传入非函数时,成功返回为x => x,失败返回为 x => throw x。然后根据状态执行相应的回调函数。then实现的代码如下:

then(onFulFilled, onRejected){onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}if(this.state === FULFILLED){onFulFilled(this.result)}else if(this.state === REJECTED){onRejected(this.result)}}

        测试代码如下所示:

const p = new MyGoPromise((resolve, reject) => {// resolve("success")reject("fail")
})p.then(res => {console.log(res)}, err => {console.log(err)})
console.log(p)

  1.3.2 then的异步支持以及多次调用

        之前的then执行的都是同步任务,需要加入对如setTimeout等异步执行的支持,修改then函数,增加判断条件pending,成立将回调暂存到隐私函数handlers中,等到rejecet或resolve时再执行,修改的代码如下(包含then和reject和resolve的调用逻辑的修改):

constructor(callback){const resolve = (result) => {// 状态只能从pending变为fulfilled或者rejectedif(this.state === PENDING){this.state = FULFILLEDthis.result = resultthis.#handlers.forEach(({onFulFilled}) => {onFulFilled(this.result)})}}const reject = (result) => {if(this.state === PENDING){this.state = REJECTEDthis.result = resultthis.#handlers.forEach(({onRejected}) => {onRejected(this.result)})}}callback(resolve, reject)}then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}if(this.state === FULFILLED){onFulFilled(this.result)}else if(this.state === REJECTED){onRejected(this.result)}else{this.#handlers.push({onFulFilled,onRejected})}}
}

 1.4 异步任务

        当我们使用下述代码测试我们已经实现的内容时会发现输出的顺序错误,代码如下所示:

// !!! 输出顺序有误 原生Promise输出为 start end success
// !!! 自定义Promise输出为 start success end
// 所以需要引入异步任务 选用核心API queueMicrotask MutationObserver setTimeout
console.log("start")
const p = new MyGoPromise((resolve, reject) => {resolve("success")
})
p.then(res => console.log(res))
console.log("end")

  1.4.1 异步主要API

        1. queueMicrotask函数直接传入回调函数即可执行

console.log("start")
queueMicrotask(()=>{console.log("queueMicrotask")
})
console.log("end")

        2.  MutationObserver notice:only works in browser 子节点改变就会执行

console.log("start")
const obs = new MutationObserver(()=>{console.log("MutationObserver")
})const divNode = document.createElement("div")
obs.observe(divNode, {childList: true})
divNode.innerHTML = "MyGo!!!!!"
console.log("end")

        3. setTimeout(callback, 0) 

  1.4.2  异步任务实现

        将异步任务执行封装成全局函数调用,用于判断以上三种异步实现浏览器是否支持,实现的runAsyncTask函数如下所示:

function runAsyncTask(callback){if(typeof queueMicrotask === "function"){queueMicrotask(callback)}else if(typeof MutationObserver === "function"){const obs = new MutationObserver(callback)const divNode = document.createElement("div")obs.observe(divNode, {childList: true})divNode.innerHTML = "MyGo!!!!!"}else{setTimeout(callback, 0)}
}

        修改then函数逻辑,将回调函数封装成异步任务执行,代码如下:

then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}if(this.state === FULFILLED){// 异步任务runAsyncTask(()=>{onFulFilled(this.result)})    }else if(this.state === REJECTED){// 异步任务runAsyncTask(()=>{onRejected(this.result)})}else{this.#handlers.push({onFulFilled:() => {// 异步任务runAsyncTask(()=>{onFulFilled(this.result)})},onRejected: () =>{// 异步任务runAsyncTask(() => {onRejected(this.result)})}})}}

 1.5 链式编程

        链式编程实现then的链式调用,错误处理,返回值处理(通常分为返回Promise 正常值 多重引用)。

  1.5.1 处理异常和普通返回值(fulfilled state)

        首先实现链式调用,使用new再then函数中创建一个全新的Promise对象,将对象返回,将之前then函数的执行逻辑放入新的Promise的回调函数当中(因为会立即执行),单独处理fulfilled分支使用try...catch...捕获错误,使用reject返回错误,获取回调函数返回值,然后resolve,代码如下:

    then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}// 在newPromise时传入的回调函数会立即执行const newPromise = new MyGoPromise((resolve, reject) => {if(this.state === FULFILLED){// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)resolve(x)} catch (error) {reject(error) }}) }else if(this.state === REJECTED){// 异步任务runAsyncTask(()=>{onRejected(this.result)})}else{this.#handlers.push({onFulFilled:() => {// 异步任务runAsyncTask(()=>{onFulFilled(this.result)})},onRejected: () =>{// 异步任务runAsyncTask(() => {onRejected(this.result)})}})}})return newPromise}

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {resolve(1)
})p.then(res =>{console.log(res)// throw "error layer1"return 100
}).then(res =>{console.log(res + " sub")
}, err =>{console.log(err + "sub")
})

  1.5.2 处理返回Promise对象 (fulfilled state)

        使用instance of判断,promise对象调用then方法处理,代码如下所示:

    then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}// 在newPromise时传入的回调函数会立即执行const newPromise = new MyGoPromise((resolve, reject) => {if(this.state === FULFILLED){// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)// 在这里处理Promise对象根据结果提交if(x instanceof MyGoPromise){x.then(res =>{resolve(res)}, err =>{reject(err)})}else{resolve(x)}} catch (error) {reject(error) }}) }else if(this.state === REJECTED){// 异步任务runAsyncTask(()=>{onRejected(this.result)})}else{this.#handlers.push({onFulFilled:() => {// 异步任务runAsyncTask(()=>{onFulFilled(this.result)})},onRejected: () =>{// 异步任务runAsyncTask(() => {onRejected(this.result)})}})}})return newPromise}
}

        测试代码如下:

// 测试代码 -- 返回Promise对象
const p = new MyGoPromise((resolve, reject) => {resolve(1)
})p.then(res =>{return new MyGoPromise((resolve, reject) => {// resolve(2)reject("error layer2")})
}).then(res =>{// 要拿到上一个Promise resolve的结果console.log(res + " sub")
}, err =>{console.log(err + "sub")
})

  1.5.3 处理重复引用 (fulfilled state)

        只需要判断我们取到的回调函数的返回值和创建的新的promise对象是否一致即可,代码(包含测试代码)如下所示:

if(x === newPromise)
{throw new TypeError("Chaining cycle detected for promise")
}// test code
const p = new MyGoPromise((resolve, reject) => {resolve(1)
})const p2 = p.then((res)=>{return p2
})

  1.5.4 处理rejected state 封装函数

        遵循同一套逻辑,首先进行错误处理,然后判断重复引用和回调结果是否是Promise对象,所以封装函数如下:

function resolvePromise(newPromise, x, resolve, reject){if(x === newPromise){throw new TypeError("Chaining cycle detected for promise")}if(x instanceof MyGoPromise){x.then(res =>{resolve(res)}, err =>{reject(err)})}else{resolve(x)}
}

         使用封装函数,代码如下:

    then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}// 在newPromise时传入的回调函数会立即执行const newPromise = new MyGoPromise((resolve, reject) => {if(this.state === FULFILLED){// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error) }}) }else if(this.state === REJECTED){// 异步任务runAsyncTask(()=>{try {const x = onRejected(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})}else{this.#handlers.push({onFulFilled:() => {// 异步任务runAsyncTask(()=>{onFulFilled(this.result)})},onRejected: () =>{// 异步任务runAsyncTask(() => {onRejected(this.result)})}})}})return newPromise}

        测试代码如下:

// 测试代码
const p = new MyGoPromise((resolve, reject) => {reject(1)
})const p2 = p.then(undefined, res =>{// return 2// return p2throw "error"// return new MyGoPromise((resolve, reject) => {//     resolve(3)// })
})p2.then((res)=>{console.log("p2-res: ", res)
}, err =>(console.log("p2-err: ", err)
))

  1.5.5 处理pending state 调用函数

        和处理fulfilled和rejected状态一样,代码如下所示:

    then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}// 在newPromise时传入的回调函数会立即执行const newPromise = new MyGoPromise((resolve, reject) => {if(this.state === FULFILLED){// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error) }}) }else if(this.state === REJECTED){// 异步任务runAsyncTask(()=>{try {const x = onRejected(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})}else{this.#handlers.push({onFulFilled:() => {// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})},onRejected: () =>{// 异步任务runAsyncTask(() => {try {const x = onRejected(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})}})}})return newPromise}

        测试代码如下:

// 测试代码
const p = new MyGoPromise((resolve, reject) => {setTimeout(()=>{resolve("success")}, 2000)
})const p2 = p.then(res =>{// return 2// return p2throw "error"// return new MyGoPromise((resolve, reject) => {//     resolve(3)// })
})p2.then((res)=>{console.log("p2-res: ", res)
}, err =>(console.log("p2-err: ", err)
))

1.6 实现catch方法

        处理错误,相当于调用then方法,但是还要处理new Promise回调里面的函数错误,修改部分代码如下:

    
//新增catch函数
catch(onRejected){// 相当于变相调用then方法return this.then(undefined, onRejected)
}// 处理实例化时的异常try {callback(resolve, reject)} catch (error) {// 处理实例化时的异常reject(error)}

        测试的代码如下所示:

// 测试代码
const p = new MyGoPromise((resolve, reject) => {throw "error"// reject("reject-error")
})p.then((res)=>{console.log("p-res: ", res)
}).catch(err =>(console.log("p-catch-err: ", err)
))

 1.7 finally实现

        不管是什么状态,最终都要执行的回调函数,也是调用then方法,只是不管是成功回调还是失败回调都是同一个回调函数,实现代码如下:

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

        测试代码如下:

const p = new MyGoPromise((resolve, reject) => {throw "error"// reject("reject-error")
})p.then((res)=>{console.log("p-res: ", res)
}).catch(err =>(console.log("p-catch-err: ", err)
)).finally(()=>{console.log("finally")
})

2 静态类方法实现

 2.1 resolve方法实现

        调用该方法将传入的值(非Promise)转换为fulfilled状态的Promise返回,如果传入Promise直接返回。

static resolve(value){if(value instanceof MyGoPromise){return value}return new MyGoPromise((resolve) => {resolve(value)})
}

        测试代码如下:

// 测试代码
const p = MyGoPromise.resolve(new MyGoPromise((resolve, reject) => {// resolve("success")reject("reject-error")})
).then(res =>{console.log("res: ", res)
}, err =>{console.log("err: ", err)
})

 2.2 reject方法实现

        不管传入什么值,直接将返回值作为原因返回rejected状态的promise,实现的代码如下:

static reject(value){return new MyGoPromise((resolve, reject) => {reject(value)})
}

        测试代码如下:

// 测试代码
MyGoPromise.reject("reject-error").catch(err =>{console.log("err: ", err)
})

 2.3 race方法实现

        race接收一个数组作为参数,返回最先完成(fulfilled)的promise对象,如果传入不是数组则拨错,实现代码如下:

static race(promises){return new MyGoPromise((resolve, reject) => {if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.forEach(promise =>{MyGoPromise.resolve(promise).then(res => {resolve(res)}, err =>{reject(err)})})})
}

        测试代码如下:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{resolve("success")}, 2000)
})const p2 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{reject("reject-error")}, 1000)
})MyGoPromise.race([p1, p2]).then(res =>{console.log("res: ", res)
}, err =>{console.log("err: ", err)
})

 2.4 all方法实现

        也是传入一个数组,有一个错误就reject,全部成功返回一个数组(按顺序),如果传入空数组直接返回空数组结果,实现代码如下:

static all(promises){// 1.返回Promise实例// 2.判断是否时数组// 3. 判断是否为空数组,空数组直接兑现// 4. 处理全部兑现 v,k 存储数据, count计数判断是否拒绝// 5. 处理拒绝 直接拒绝即可return new MyGoPromise((resolve, reject) => {if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.length === 0 && resolve([])let count = 0const result = []promises.forEach((promise, index) => {MyGoPromise.resolve(promise).then(res =>{result[index] = rescount ++count === promises.length && resolve(result)}, err =>{reject(err)})})}) 
}

        测试代码如下所示:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{resolve("success 1")}, 2000)
})const p2 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{resolve("success 2")}, 1000)
})MyGoPromise.all([p1, p2]).then(res =>{console.log("res: ", res)
}, err =>{console.log("err: ", err)
})

 2.5 allsettled方法实现

        无论成功还是失败,都是返回一个对象数组,数组中存储state和value以及reason,基本照搬all方法的实现,代码如下:

static allsettled(promises){return new MyGoPromise((resolve, reject) => {if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.length === 0 && resolve([])let count = 0const result = []promises.forEach((promise, index) => {MyGoPromise.resolve(promise).then(res =>{result[index] = {value: res,status: "fulfilled",}count ++count === promises.length && resolve(result)}, err =>{result[index] = {reason: err,status: "rejected"}count ++count === promises.length && resolve(result)})})}) 
}

        测试代码如下所示:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{resolve("success 1")}, 2000)
})const p2 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{reject("success 2")}, 1000)
})MyGoPromise.allsettled([1, p1, p2]).then(res =>{// 会打印成功和失败的结果console.log("res: ", res)
}, err =>{console.log("err: ", err)
})

 2.6 any方法实现

        任意一个成功就返回成功,全部失败才返回失败,和all反着来,但是在any方法中,如果传入空数组也会有aggregate的报错,是新代码如下:

static any(promises){return new MyGoPromise((resolve, reject)=>{if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.length === 0 && reject(new AggregateError([]))let count = 0const errors = []promises.forEach((promise, index)=>{MyGoPromise.resolve(promise).then(res => {resolve(res)}, err => {errors[index] = errcount ++count === promises.length && reject(new AggregateError(errors))})})})
}

        测试代码如下所示:

// 测试代码
const p1 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{resolve("success 1")}, 2000)
})const p2 = new MyGoPromise((resolve, reject) => {setTimeout(()=>{reject("success 2")}, 1000)
})MyGoPromise.any([p1, p2, MyGoPromise.reject(1)]).then(res =>{// 会打印第一个成功的结果 1console.log("res: ", res)
}, err =>{console.log("err: ", err)
})

3 完整代码展示

function runAsyncTask(callback){if(typeof queueMicrotask === "function"){queueMicrotask(callback)}else if(typeof MutationObserver === "function"){const obs = new MutationObserver(callback)const divNode = document.createElement("div")obs.observe(divNode, {childList: true})divNode.innerHTML = "MyGo!!!!!"}else{setTimeout(callback, 0)}
}function resolvePromise(newPromise, x, resolve, reject){if(x === newPromise){throw new TypeError("Chaining cycle detected for promise")}if(x instanceof MyGoPromise){x.then(res =>{resolve(res)}, err =>{reject(err)})}else{resolve(x)}
}const PENDING = "pending"
const FULFILLED = "fulfilled"
const REJECTED = "rejected"
class MyGoPromise{state = PENDINGresult = undefined// 使用对象数组保存pending时候的失败调用和成功调用#handlers = []constructor(callback){const resolve = (result) => {// 状态只能从pending变为fulfilled或者rejectedif(this.state === PENDING){this.state = FULFILLEDthis.result = resultthis.#handlers.forEach(({onFulFilled}) => {onFulFilled(this.result)})}}const reject = (result) => {if(this.state === PENDING){this.state = REJECTEDthis.result = resultthis.#handlers.forEach(({onRejected}) => {onRejected(this.result)})}}try {callback(resolve, reject)} catch (error) {// 处理实例化时的异常reject(error)}}then(onFulFilled, onRejected){// 当传入的值不是函数时,需要按照以下两种形式返回onFulFilled = typeof onFulFilled === "function" ? onFulFilled : x => xonRejected = typeof onRejected === "function" ? onRejected : e => {throw e}// 在newPromise时传入的回调函数会立即执行const newPromise = new MyGoPromise((resolve, reject) => {if(this.state === FULFILLED){// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error) }}) }else if(this.state === REJECTED){// 异步任务runAsyncTask(()=>{try {const x = onRejected(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})}else{this.#handlers.push({onFulFilled:() => {// 异步任务runAsyncTask(()=>{try {const x = onFulFilled(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})},onRejected: () =>{// 异步任务runAsyncTask(() => {try {const x = onRejected(this.result)resolvePromise(newPromise, x, resolve, reject)} catch (error) {reject(error)}})}})}})return newPromise}catch(onRejected){// 相当于变相调用then方法return this.then(undefined, onRejected)}finally(onFinally){return this.then(onFinally, onFinally)}static resolve(value){if(value instanceof MyGoPromise){return value}return new MyGoPromise((resolve) => {resolve(value)})}static reject(value){return new MyGoPromise((resolve, reject) => {reject(value)})}static race(promises){return new MyGoPromise((resolve, reject) => {if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.forEach(promise =>{MyGoPromise.resolve(promise).then(res => {resolve(res)}, err =>{reject(err)})})})}static all(promises){// 1.返回Promise实例// 2.判断是否时数组// 3. 判断是否为空数组,空数组直接兑现// 4. 处理全部兑现 v,k 存储数据, count计数判断是否拒绝// 5. 处理拒绝 直接拒绝即可return new MyGoPromise((resolve, reject) => {if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.length === 0 && resolve([])let count = 0const result = []promises.forEach((promise, index) => {MyGoPromise.resolve(promise).then(res =>{result[index] = rescount ++count === promises.length && resolve(result)}, err =>{reject(err)})})}) }static allsettled(promises){return new MyGoPromise((resolve, reject) => {if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.length === 0 && resolve([])let count = 0const result = []promises.forEach((promise, index) => {MyGoPromise.resolve(promise).then(res =>{result[index] = {value: res,status: "fulfilled",}count ++count === promises.length && resolve(result)}, err =>{result[index] = {reason: err,status: "rejected"}count ++count === promises.length && resolve(result)})})}) }static any(promises){return new MyGoPromise((resolve, reject)=>{if(!Array.isArray(promises)){reject(new TypeError("Argument is not iterable"))}promises.length === 0 && reject(new AggregateError([]))let count = 0const errors = []promises.forEach((promise, index)=>{MyGoPromise.resolve(promise).then(res => {resolve(res)}, err => {errors[index] = errcount ++count === promises.length && reject(new AggregateError(errors))})})})}}

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

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

相关文章

Java面试:ArrayList 和 LinkedList 的区别是什么?谈谈你对ArrayList和LinkedList的理解

在 Java 的集合框架中,ArrayList 和 LinkedList 是两种常用的 List 实现。它们各具特点,适用于不同的场景。本文将深入探讨这两种数据结构的概念、用法、联系和区别,帮助你选择合适的集合类来满足特定需求。 一、基本介绍 1. ArrayList Ar…

C/C++进阶(一)--内存管理

更多精彩内容..... 🎉❤️播主の主页✨😘 Stark、-CSDN博客 本文所在专栏: 学习专栏C语言_Stark、的博客-CSDN博客 其它专栏: 数据结构与算法_Stark、的博客-CSDN博客 ​​​​​​项目实战C系列_Stark、的博客-CSDN博客 座右铭&a…

D3.js数据可视化基础——基于Notepad++、IDEA前端开发

实验:D3.js数据可视化基础 1、实验名称 D3数据可视化基础 2、实验目的 熟悉D3数据可视化的使用方法。 3、实验原理 D3 的全称是(Data-Driven Documents),是一个被数据驱动的文档,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可视化的。本次实…

【前沿 热点 顶会】NIPS 2024中目标检测有关的论文

迈向灵活的 3D 感知:以对象为中心的占领完成增强长序列的 3D 目标检测 虽然 3D 对象边界框(BBox)表示在自动驾驶感知中得到了广泛的应用,但它们缺乏捕捉对象内部几何形状的复杂细节的能力。最近,占有(occupancy)已经成…

大数据-151 Apache Druid 集群模式 配置启动【上篇】 超详细!

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

《Linux从小白到高手》理论篇(六):Linux软件安装一篇通

List item 本篇介绍Linux软件安装相关的操作命令,看完本文,有关Linux软件安装相关操作的常用命令你就掌握了99%了。 Linux软件安装 RPM RPM软件的安装、删除、更新只有root权限才能使用;查询功能任何用户都可以操作;如果普通用…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset(模拟实现)

1.对红黑树进行改造 1.1treenode模板参数改变 之前构建treenode模板参数传的是class k,class v(set为k&#xff0c;k&#xff1b;map是k&#xff0c;v&#xff09;&#xff0c;现在直接用T代替 template<class T> //这里直接传了T作为模板参数&#xff0c;T可能是pai…

【WRF工具】cmip6-to-wrfinterm工具概述:生成WRF中间文件

cmip6-to-wrfinterm工具概述 cmip6-to-wrfinterm工具安装cmip6-to-wrfinterm工具使用快速启动&#xff08;Quick start&#xff09;情景1&#xff1a;MPI-ESM-1-2-HR&#xff08;默认&#xff09;&#xff1a;情景2&#xff1a;BCMM情景3&#xff1a;EC-Earth3 更改使用&#x…

Hive数仓操作(四)

一、Hive 创建表案例一&#xff08;ARRAY数组类型&#xff09; 1. 准备数据文件 首先&#xff0c;准备一个名为 stu2.txt 的文件&#xff0c;文件内容示例如下&#xff1a; 1001 Alice fish,cat 1002 Bob dog,rabbit 1003 Charlie bird注意&#xff1a; …

进度条(倒计时)Linux

\r回车(回到当前行开头) \n换行 行缓冲区概念 什么现象&#xff1f; 什么现象&#xff1f;&#xff1f; 什么现象&#xff1f;&#xff1f;&#xff1f; 自己总结&#xff1a; #pragma once 防止头文件被重复包含 倒计时 在main.c中&#xff0c;windows.h是不可以用的&…

大语言模型入门(一)——大语言模型智能助手

一、大语言模型智能助手 2022年末ChatGPT一经推出&#xff0c;一时间不注册个账号用一下都跟不上潮流了。然而&#xff0c;我们要注册OpenAI的账号使用ChatGPT还是一件比较麻烦的事情&#xff08;懂的都懂&#xff09;。好在&#xff0c;国内各大团队非常给力地及时推出了自研的…

计算机网络--TCP、UDP抓包分析实验

计算机网络实验 目录 实验目的 实验环境 实验原理 1、UDP协议 2、TCP协议 实验具体步骤 实验目的 1、掌握使用wireshark工具对UDP协议进行抓包分析的方法&#xff0c;掌握UDP协议的报文格式&#xff0c;掌握UDP协议校验和的计算方法&#xff0c;理解UDP协议的优缺点&am…

探索、深化技能与软实力共进

在当下的大语言模型AIGC快速发展的时代&#xff0c;AI辅助编程工具的普及正在深刻改变程序员的工作方式。面对这一变革&#xff0c;程序员如何保持并提升自身的核心竞争力&#xff0c;是每个程序员都需要思考的问题。  一、认知AI的力量  AI技术的发展和普及为程序员提供了…

Linux云计算 |【第四阶段】RDBMS1-DAY3

主要内容&#xff1a; 子查询&#xff08;单行单列、多行单列、单行多列、多行多列&#xff09;、分页查询limit、联合查询union、插入语句、修改语句、删除语句 一、子查询 子查询就是指的在一个完整的查询语句之中&#xff0c;嵌套若干个不同功能的小查询&#xff0c;从而一…

《OpenCV》—— 指纹验证

用两张指纹图片中的其中一张对其验证 完整代码 import cv2def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)def verification(src, model):sift cv2.SIFT_create()kp1, des1 sift.detectAndCompute(src, None)kp2, des2 sift.detectAndCompute(model, None)fl…

stm32四足机器人(标准库)

项目技术要求 PWM波形的学习 参考文章stm32 TIM输出比较(PWM驱动LED呼吸灯&&PWM驱动舵机&&PWM驱动直流电机)_ttl pwm 驱动激光头区别-CSDN博客 舵机的学习 参考文章 stm32 TIM输出比较(PWM驱动LED呼吸灯&&PWM驱动舵机&&PWM驱动直流电机)…

Pikichu-xss实验案例-通过xss获取cookie

原理图&#xff1a; pikachu提供了一个pkxss后台&#xff1b; 该后台可以把获得的cookie信息显示出来&#xff1b; 查看后端代码cookie.php&#xff1a;就是获取cookie信息&#xff0c;保存起来&#xff0c;然后重定向跳转到目标页面&#xff1b;修改最后从定向的ip&#xff0…

计算机组成原理之乘/除法运算的基本原理,乘法电路与除法电路的基本结构

计算机组成原理之乘/除法运算的基本原理 乘法运算&#xff1a; 基本原理&#xff1a;在计算机中&#xff0c;乘法运算通常通过累加-左移&#xff08;对于二进制乘法&#xff09;或利用阵列乘法器实现。累加-左移方法通过将被乘数与乘数的每一位相乘&#xff08;与操作&#x…

V3D——从单一图像生成 3D 物体

导言 论文地址&#xff1a;https://arxiv.org/abs/2403.06738 源码地址&#xff1a;https://github.com/heheyas/V3D.git 人工智能的最新进展使得自动生成 3D 内容的技术成为可能。虽然这一领域取得了重大进展&#xff0c;但目前的方法仍面临一些挑战。有些方法速度较慢&…

c语言基础作业

选择题 1.1、以下选项中,不能作为合法常量的是 __________ A&#xff09;1.234e04 B&#xff09;1.234e0.4C&#xff09;1.234e4 D&#xff09;1.234e0 1.2、以下定义变量并初始化错误的是_____________。 A) char c1 ‘H’ &#xff1b; B) char c1 9…