模块一 part1
异步 1
历史背景: JS 诞是为了操作 DOM 元素,为了防止多线程操作 DOM 发生冲突,JS 只能成为一门单线程的语言。为了防止一个任务执行时间过长 JS 提出了异步解决方案。
分类: JS 分成了两种情况,第一种是 JS 运行在浏览器端,另一种是运行在 nodeJS 上,因此就形成了两种截然不同的异步方案。
浏览器的异步方案:
- 浏览器解析 JS 代码,将全局上下文压入函数执行栈
- 引擎开始执行代码,遇到函数调用时压入执行栈
- 当引擎遇到异步函数调用时,浏览器会单独开一个线程(webAPI)来执行这些异步函数
- 当 webAPI 执行完异步函数后,会将回调函数放入消息队列中
- 当 promise 诞生时,浏览器需要一个优先级更高的消息队列,这就产生了微任务,微任务队列在每一个宏任务执行完之后都会检查并执行完。
异步 2
new Promise((resolve, reject) => {
const a = "hello";
setTimeout(() => {
resolve(a);
}, 10);
})
.then(value => {
const b = "lagou";
return value + b;
})
.then(value => {
const c = "iloveu";
console.log(value + c);
});
函数式 1
const fp = require("lodash/fp");
const findProp = fp.curry(fp.prop)
const find = fp.flowRight(findProp("in_stock"), fp.last);
console.log(find(cars));
函数式 2
const fp = require("lodash/fp");
const findProp = fp.curry(fp.prop);
const findFirst = fp.flowRight(findProp("name"),fp.first)
console.log(findFirst(cars));
函数式 3
const _average = function(xs) {
return xs.reduce(fp.add, 0) / xs.length;
};
const getValue = fp.curry(fp.map);
const getDollarValue = getValue(item => {
return item.dollar_value;
});
const getAverage = fp.flowRight(_average, getDollarValue);
console.log(getAverage(cars));
函数式 4
const curriedMap = fp.curry(fp.map);
const handName = curriedMap(item => {
return item.name;
});
const _underscore = fp.replace(/\W+/g, "_");
const handReplaceName = curriedMap(_underscore);
const handUpper = curriedMap(fp.toUpper);
const sanitizeNames = fp.flowRight(handUpper, handReplaceName, handName);
console.log(sanitizeNames(cars));
函子 1
const fp = require("lodash/fp");
class Container {
static of(value) {
return new Container(value);
}
constructor(value) {
this._value = value;
}
map(fn) {
return Container.of(fn(this._value));
}
}
class MayBe {
static of(x) {
return new MayBe(x);
}
isNothing() {
return this._value === null || this._value === undefined;
}
constructor(x) {
this._value = x;
}
map(fn) {
return this.isNothing() ? this : MayBe.of(fn(this._value));
}
}
let mayBe = MayBe.of([5, 6, 1]);
const curriedMap = fp.curry(fp.map)
const addNum = fp.curry(fp.add)
const add1 = addNum(1)
const handleAdd = curriedMap(add1)
const ex1 = ()=>{
mayBe = mayBe.map(handleAdd)
}
ex1()
console.log(mayBe._value);
函子 2
let xs = Container.of(["do", "ray", "me", "fa", "so", "la", "ti", "do"]);
const ex2 = ()=>{
return xs.map(fp.first)
}
console.log(ex2());
函子 3
const safeProp = fp.curry(function (x,o) {
return MayBe.of(o[x])
})
const user = {id:2,name:"Albert"}
const ex3 = ()=>{
const getName = safeProp("name")
return getName(user).map(fp.first)
}
console.log(ex3());
函子 4
const ex4 = function (n) {
return MayBe.of(n).map(parseInt)
}
console.log(ex4("1"));
MyPromise
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
status = PENDING;
value = undefined;
reason = undefined;
onResolvedCallbacks = [];
onRejectedCallbacks = [];
resolve(value) {
if (this.status !== PENDING) return;
status = FULFILLED;
this.value = value;
this.onResolvedCallbacks.forEach(fn => {
fn();
});
}
reject(reason) {
if (this.status !== PENDING) return;
status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => {
fn();
});
} //resolve reject 两个回调函数接受value 和 reason 两个参数
constructor(executor) {
try {
executor(this.resolve, this.reject); // new MyPromise() 调用时传入的函数式是交执行函数
} catch (e) {
this.reject(e);
}
}
then(onFulfilled, onRejected) {
// onFulfilled,onRejected 两个回调默认传入两个参数
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected =
typeof onRejected === "function"
? onRejected
: err => {
throw err;
};
const promise2 = new Promise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
static resolve(value) {
if (value instanceof Promise) return value;
return new Promise(resolve => resolve(value));
}
static all(array) {
let result = [];
let index = 0;
return new Promise((resolve, reject) => {
function addDate(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
array.forEach((item, index) => {
if (item instanceof Promise) {
item.then(
value => addDate(index, value),
reason => reject(reason)
);
} else {
addDate(index, item);
}
});
});
}
finally(callback) {
return this.then(
value => {
return Promise.resolve(callback()).then(() => value);
},
reason => {
return Promise.resolve(callback()).then(() => throw reason);
}
);
}
catch(callback) {
return this.then(undefined, callback);
}
}
function resolvePromise(promise, x, resolve, reject) {
if (x === promise)
return reject(new TypeError("Chaining cycle detected for promise"));
if (x instanceof Promise) {
x.then(resolve, reject); //onFulfilled回调默认传入参数,resolve回调函数接受value,resolve 作为 onFulfilled刚刚好
} else {
resolve(x);
}
}