跳到主要内容

异步

实现 promise

function Promise(fn) {
this.cbs = [];

const resolve = (value) => {
setTimeout(() => {
this.data = value;
// 这个value,循环体现在 a.then();a.then();会增加cb;所以value值不变
// 而a.then().then()其实是创造一个新的promise (a.then())来管理新cb,value值需要更新
this.cbs.forEach((cb) => cb(value));
});
};
// 执行器,很关键,一切从这开始
fn(resolve);
}

Promise.prototype.then = function (onResolved) {
// 返回一个新promise从而可以链式调用,而这个promise会立即往自身的cb里加入一个函数
// 这个函数能保证then时,老promise resolve时会把新promise的onResolved执行了
// 在调用resolve会遍历cb,并异步执行里面的函数,那么就会进而执行onResolved
// 给完成结果加上then再resolve能再下一次异步执行res(promise)独享的cb2
// 如果完成结果不是promise,直接通过resolve派发这一次then的结果,更新this.data
return new Promise((resolve) => {
this.cbs.push(() => {
// 这一行则完成了.then((res)=>{}),并且将老promise的data传给新promise
const res = onResolved(this.data);
if (res instanceof Promise) {
res.then(resolve);
} else {
resolve(res);
}
});
});
};

new Promise((resolve) => {
setTimeout(() => {
resolve(1);
}, 500);
})
.then((res) => {
console.log(res);
return new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, 500);
});
})
.then(console.log);

hardman

HardMan(“jack”) 输出:
I am jack

HardMan(“jack”).rest(10).learn(“computer”) 输出
I am jack
//等待10秒
Start learning after 10 seconds
Learning computer

HardMan(“jack”).restFirst(5).learn(“chinese”) 输出
//等待5秒,但是优先级比I am jack还搞·
Start learning after 5 seconds
I am jack
Learning chinese


class _HardMan {
constructor(name) {
this.tasks = []
// 重点是这个timeout和await
setTimeout(async () => {
for (let task of this.tasks) {
await task()
}
})

this.tasks.push(() =>
new Promise(resolve => {
console.log(`I am ${name}`)
resolve()
})
)
}

wait(sec) {
return new Promise(resolve => {
console.log(`//等待${sec}秒..`)
setTimeout(() => {
console.log(`Start learning after ${sec} seconds`)
resolve()
}, sec * 1000);
})
}


rest(sec) {
this.tasks.push(() => this.wait(sec))
return this
}

restFirst(sec) {
this.tasks.unshift(() => this.wait(sec))
return this
}

learn(params) {
this.tasks.push(() =>
new Promise(resolve => {
console.log(`Learning ${params}`)
resolve()
})
)
return this
}


}

//类式写法还想用Hardman(),包一层吧
function HardMan(name) {
return new _HarnMan(name)
}



// 解答分析:
// 1. 链式调用,每一个方法都返回this
// 2. 并不直接执行代码,而是使用SetTimeout,这样就先把想要执行的任务先放进队列再执行
// 3. wait 的使用,使用setTimeout,如果不用Promise把setTimeout包住,就无法堵塞后面代码的执行
// 4. 除了用Promise,也可以在每个任务中指定的调用下一个任务,如:

// 另一种写法,需要手动启动run,constructor就不用setTimeout了
next() {
let task = this.tasks.shift()
task && task()
}

wait(sec) {
setTimeout(() => {
//do something
this.next()
}, sec)
}

// 还可以准备一个run
run(){
const runTask = async () => {
for (let task of this.tasks) {
await task()
}
}
runTask()
return this
}


promise 超时

function promiseUtil(promise) {
return Promise.race([
promise,
new Promise((_, reject) => {
setTimeout(() => {
reject("error");
}, 5000);
}),
]);
}

promise.resolve()

Promise.resolve = function (data) {
if (data instanceof Promise) {
return data;
}
return new Promise((resolve) => {
resolve(data);
});
};

一个每隔 s 秒执行一次,一共执行 n 次

function repeatFunction(interval, repetitions, func, ...args) {
let count = 0;
const intervalId = setInterval(() => {
if (count >= repetitions) {
clearInterval(intervalId);
} else {
func(...args);
count++;
}
}, interval * 1000); // Convert seconds to milliseconds
}

// Example usage:
function myFunction() {
console.log("Function executed");
}

// Execute `myFunction` every 2 seconds, 5 times
repeatFunction(2, 5, myFunction);

实现 setInterval + clearInterval(闭包存储定时器)

function fn() {
console.log(1);
}

const timeWorker = {}; // 全局变量

// 实现setInterval
function mySetInterval(fn, delay) {
const key = Symbol();
const execute = function (fn, delay) {
timeWorker[key] = setTimeout(function () {
fn();
execute(fn, delay);
}, delay);
};
// 第一次启动
execute(fn, delay);

// key需要return到外界
return key;
}

let timerID = mySetInterval(fn, 1000);

// 实现clearInterval
function myClearInterval(key) {
if (key in timeWorker) {
// 调用原生setTimeout清除,{自定义key:原生setTimeout的key}
clearTimeout(timeWorker[key]);
delete timeWorker[key];
}
}

setTimeout(() => {
myClearInterval(timerID);
}, 5000);