手写深拷贝和 Promise
深拷贝
js
function deepClone(obj, map = new Map()) {
// return JSON.parse(JSON.stringify(obj))
if (typeof obj !== "object" || obj === null) {
return obj;
}
let copy = Array.isArray(obj) ? [] : {};
if (map.get(obj)) {
return map.get(obj);
}
map.set(obj, copy);
if (Array.isArray(obj)) {
for (let i = 0; i++; i < obj.length) {
copy[i] = deepClone(obj[i]);
}
} else {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepClone(obj[key], map);
}
}
}
return copy;
}
Promise
手写 promise
js
// 手写promise
class MyPromise {
constructor(callback) {
this.status = "pending";
this.value = null;
this.reason = null;
this.onResolvedCallbacks = new Array();
this.onRejectedCallbacks = new Array();
this.resolve = (value) => {
if (this.status === "pending") {
this.value = value;
this.status = "resolved";
this.onResolvedCallbacks.map((cb) => cb());
}
};
this.reject = (reason) => {
if (this.status === "pending") {
this.reason = reason;
this.status = "rejected";
this.onRejectedCallbacks.map((cb) => cb());
}
};
callback(this.resolve, this.reject);
}
then(onResolve, onReject) {
onResolve = typeof onResolve === "function" ? onResolve : (x) => x;
onReject =
typeof onReject === "function"
? onReject
: (x) => {
throw x;
};
const newPromise = new MyPromise((resolve, reject) => {
if (this.status === "resolved") {
try {
const x = onResolve(this.value);
resolve(x);
} catch (err) {
reject(err);
}
} else if (this.status === "rejected") {
try {
const x = onReject(this.reason);
resolve(x);
} catch (err) {
reject(err);
}
}
if (this.status === "pending") {
this.onResolvedCallbacks.push(() => {
if (this.status === "resolved") {
try {
const x = onResolve(this.value);
resolve(x);
} catch (err) {
reject(err);
}
}
});
this.onRejectedCallbacks.push(() => {
if (this.status === "rejected") {
try {
const x = onReject(this.reason);
resolve(x);
} catch (err) {
reject(err);
}
}
});
} else {
this.onRejectedCallbacks = [];
this.onResolvedCallbacks = [];
}
});
return newPromise;
}
catch = (onReject) => this.then(null, onReject);
}
手写 promise.all
js
// 手写 promise.all
const promiseAll = (values) => {
const resArr = [];
let orderIndex = 0;
const promise = new Promise((resolve, reject) => {
const addPromiseRes = (value, index) => {
resArr[index] = value;
if (++orderIndex === values.length) {
resolve(resArr);
}
};
for (let i = 0; i < values.length; i++) {
if (values[i] && typeof values[i].then === "function") {
values[i].then((res) => {
addPromiseRes(res, i);
}, reject);
} else {
addPromiseRes(values[i], i);
}
}
});
return promise;
};
手写 promise.race 并封装中断
js
// 手写promise.race 并封装中断
const promiseRace = (values) => {
const promise = new Promise((resolve, reject) => {
for (let i = 0; i < values.length; i++) {
values[i].then((res) => {
resolve(res);
}, reject);
}
});
return promise;
};
const wrap = (fn) => {
let abort;
const newPromise = new Promise((_, reject) => {
abort = reject;
});
const p = promiseRace([fn, newPromise]);
p.abort = abort;
return p;
};
手写 promisefy
js
// 手写 promisefy
const promisefy = (fn) => {
return (...args) => {
return new Promise((resolve, reject) => {
fn(...args, function (err, data) {
// node中的回调函数的参数 第一个永远是error
if (err) return reject(err);
resolve(data);
});
});
};
};