模块一 part1

303 阅读3分钟

模块一 part1

异步 1

历史背景: JS 诞是为了操作 DOM 元素,为了防止多线程操作 DOM 发生冲突,JS 只能成为一门单线程的语言。为了防止一个任务执行时间过长 JS 提出了异步解决方案。

分类: JS 分成了两种情况,第一种是 JS 运行在浏览器端,另一种是运行在 nodeJS 上,因此就形成了两种截然不同的异步方案。

浏览器的异步方案:

  1. 浏览器解析 JS 代码,将全局上下文压入函数执行栈
  2. 引擎开始执行代码,遇到函数调用时压入执行栈
  3. 当引擎遇到异步函数调用时,浏览器会单独开一个线程(webAPI)来执行这些异步函数
  4. 当 webAPI 执行完异步函数后,会将回调函数放入消息队列中
  5. 当 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);
  }
}