你不知道的JavaScript(中)笔记
Opened this issue · 3 comments
hujiejeff commented
你不知道的JavaScript(中)笔记
hujiejeff commented
Web Worker
what
提供一种多线程的运行方式
通过创建web worker创建一个在后台线程运行的js程序
how
通过发送消息和监听消息完成主线程和worker线程的通讯
//主线程加载另一个文件
let worker = new Worker("./worker.js");
//添加消息监听
worker.addEventListener("message", ev => {
console.log(ev);
console.log("idnex page is received");
let p = document.createElement("p");
p.innerText = "idnex page is received";
console.log(ev.data);
app.appendChild(p);
});
//发送消息
worker.postMessage("hello");
在worker.js中
console.log(this);
this.addEventListener("message", ev => {
console.log(ev);
console.log("worker is received");
this.postMessage("halo");
});
hujiejeff commented
尾调用
函数调用于与返回实际上一个栈帧的入栈和出栈,如果在return 语句仅进行函数调用,栈帧得到复用,节省了内存以及后续大量的入栈出栈时间。
what
尾部直接调用另一函数,不在函数调用外进行运算。这样进行尾调用时,栈帧得以复用。在递归场景下,使用尾递归优化可以实现很好的性能优化
function f1(a) {
}
function f2() {
//do something
let a = 10;
return f1(a + 10);//尾调用
}
function f3() {
let a = 10;
return f3(a) + 10;//非尾调用
}
比如打印一个斐波那契数列
糟糕的实现
function f(n) {
if (n < 0) {
return 0;
}
if (n === 0 || n === 1) {
return 1;
}
return f(n - 1) + f(n - 2);
}
这种状况下返回时,除了本身的栈帧,然后又会压入f(n-1) 和f(n-2),两个栈帧,然后递归中又是压入n多个栈帧。
尾递归优化
function fibonacci(n) {
function fib(n, v1, v2) {
if (n == 1)
return v1;
if (n == 2)
return v2;
else
return fib(n - 1, v2, v1 + v2)
}
return fib(n, 1, 1)
}
fibonacci(30)
hujiejeff commented
简易版Promise实现
class MyPromise {
status = 'pending';
data;
constructor(executor) {
executor(this.resolve.bind(this), this.reject.bind(this));
}
then(onSucessCallback, onFailedCallback) {
return new MyPromise((resolve, reject) => {
if (this.status === 'resolved') {
//状态完成,直接执行
setTimeout(() => {
resolve(onSucessCallback(this.data));
});
} else if (this.status === 'rejected') {
//状态完成,直接执行
setTimeout(() => {
reject(onFailedCallback(this.data));
});
} else if (this.status === 'pending') {
//状态准备,启用回调
this.onSucessCallback = (res) => {
resolve(onSucessCallback(res));
};
this.onFailedCallback = (err) => {
reject(onFailedCallback(err));
};
}
});
}
resolve(res) {
if (this.status === 'pending') {
this.data = res;
this.status = 'resolved';
if (typeof this.onSucessCallback === 'function') {
setTimeout(() => this.onSucessCallback(res), 0);
}
}
}
reject(err) {
if (this.status === 'pending') {
this.data = err;
if (typeof this.onFailedCallback === 'function') {
setTimeout(() => this.onFailedCallback(err), 0)
}
}
}
static all(...promises) {
let sucessCount = 0;
let hasErrCalled = false;
let results = [];
return new MyPromise((resovle, reject) => {
for (let promise of promises) {
promise.then(res => {
results.push(res);
sucessCount++;
if (sucessCount === promises.length) {
resovle(results);
}
}, err => {
if (!hasErrCalled) {
hasErrCalled = true;
reject(err);
}
});
}
});
}
}