http1和http2的区别
http和https的区别
webpack热更新原理
JS设计模式
JS面向对象
组建挂在到vue原型
限制请求并发JS
队列的「先进先出」特性可以保证任务并发执行的顺序,在 JavaScript 中可以通过「数组来模拟队列」 juejin.cn/post/691222…
使用生成器函数 juejin.cn/post/717618…
webpack 原理,附带常见面试题
请求options方法
其实,这是因为在跨域的情况下,在浏览器发起"复杂请求"时主动发起的。跨域共享标准规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
某些请求不会触发 CORS 预检请求,这样的请求一般称为"简单请求",而会触发预检的请求则成为"复杂请求"。 juejin.cn/post/684490…
微任务宏任务执行、微任务有哪些、宏任务有哪些
JavaScript中任务被分为两种,一种叫宏任务,一种叫微任务,它们在Event Loop机制中也扮演着至关重要的角色,与各种异步任务的执行顺序息息相关。
宏任务(Macro Task):
整个script 定时器任务,如setTimeout、setInterval。 浏览器事件,如click、mouseover。 网络请求,如fetch、XMLHttpRequest。 UI渲染,如重绘。
微任务(Micro Task):
Promise的回调函数 Async/Await 函数 MutationObserver的回调函数 process.nextTick Node.js环境下
执行顺序
先执行整个script这个宏任务,其中会包含各种小的宏任务以及微任务,从上至下,碰到同步任务就执行,碰到宏任务先放进宏任务队列,碰到微任务就放到微任务队列,当script这个宏任务执行到底时,就开始执行微任务队列里面的任务,执行完里面的微任务后去宏任务队列拿一个任务出来,如果这个宏任务里面又有许多微任务那就照样放进微任务队列,等待这个宏任务执行完后再执行微任务队列中的任务。 总结一下:最开始执行的一定是宏任务,然后这个宏任务中的微任务会先于其中的宏任务执行。
nextTick 的作用是什么?他的实现原理是什么?
在下次 DOM 更新循环结束之后执行延迟回调。nextTick主要使用了宏任务和微任务。根据执行环境分别尝试采用
Promise MutationObserver setImmediate 如果以上都不行则采用setTimeout
定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列
手写Promise
class myPromise {
constructor(executor) {
this.status = 'pending'
this.value = undefined
this.reason = undefined
this.onFulfilledCallback = [] //then 的回调
this.onRejectedCallback = [] //catch 的回调
// 改变Promise状态为fulfilled,并调用所有成功的回调函数
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled'
this.value = value
//then 的回调在这里触发
this.onFulfilledCallback.forEach(callback => callback(value))
}
}
// 改变Promise状态为rejected,并调用所有失败的回调函数
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'
this.reason = reason
//catch 的回调在这里触发
this.onRejectedCallback.forEach(callback => callback(reason))
}
}
executor(resolve, reject)
}
// then方法用于注册成功和失败的回调函数
then(onFulfilled, onRejected) {
// 处理默认情况,如果没有提供回调函数,则使用默认函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
const newPromise = new myPromise((resolve, reject) => {
if(this.status === 'fulfilled') {
setTimeout(() => {
try {
const result = onFulfilled(this.value)
resolve(result)
}
catch (error) {
reject(error)
}
}, 0)
}
if(this.status === 'rejected') {
setTimeout(() => { // 模拟异步,但是模拟不了微任务
try {
const result = onRejected(this.reason)
resolve(result)
}
catch (error) {
resolve(error)
}
}, 0)
}
// 如果Promise处于pending状态,则将回调函数保存到队列中
if (this.status === 'pending') {
this.onFulfilledCallback.push(() => {
setTimeout(() => {
try {
const result = onFulfilled()
resolve(result)
} catch (error) {
reject(error)
}
},0)
})
this.onRejectedCallback.push(()=> {
setTimeout(() => {
try {
const result = onRejected()
resolve(result)
} catch (error) {
reject(error)
}
},0)
})
}
})
return newPromise
}
}
constructor(executor) {...}:myPromise类的构造函数,它接受一个executor函数作为参数。这个executor函数应该有两个参数:resolve和reject。resolve和reject是两个函数,用于改变 Promise 的状态并传递相应的值。
then(onFulfilled, onRejected) {...}:then方法用于注册成功和失败的回调函数。它接受两个可选参数:onFulfilled和onRejected。如果onFulfilled或onRejected没有被提供,then方法将使用默认的函数。
冒泡排序
Array.prototype.bubbleSort=function(){
for(let i=0;i<this.length-1;i++){
for(let j=0;j<this.length-1-i;j++){
if(this[j]>this[j+1]){
const temp=this[j]
this[j]=this[j+1]
this[j+1]=temp
}
}
}
return this
}
选择排序
const arr = [1, 3, 5, 3, 2, 18, 26, 1, 33, 92, 157, 48, 9, 762, 128];
const selectSort = (arr) => {
const len = arr.length;
let temp, minIndex;
for (let i = 0; i < len - 1; i++) {
minIndex = i;
for (let j = i + 1; j < len; j++) {
if (arr[j] <= arr[minIndex]) {
minIndex = j
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
};
console.log(selectSort(arr));