[记录]我的日常随笔(二)

简介: [记录]我的日常随笔(二)
  1. JS 模块化
AMD: require.js 为代表,依赖前置,一律先加载再使用。
CMD: sea.js 为代表,依赖就近原则。
UMD: 兼容AMD和commonJS规范的同时,还兼容全局引用的方式。
ES6 import/export

15.你从未注意的隐藏危险: target = "\_blank" 和 "opener"

// 最佳实践
<a href="https://an.evil.site" target="_blank"
   rel="noopener noreferrer nofollow">
  Enter an "evil" website
</a>

16.阶乘

function factorial(num, sum = 1) {
    if(num <= 1)return sum;
    sum *= num;
    return factorial(--num, sum); // 尾递归
}
factorial(3) // -> 6

17.柯里化

const curry = (fn , args = []) => {
    return (...rets) => {
        const allArgs = args.concat(rets);
        if(allArgs.length < fn.length) {
            return curry(fn, allArgs);
        } else {
            return fn.apply(this, allArgs);
        }
    }
}
function multiFn(a, b, c) {
    return a * b * c;
}

var multi = curry(multiFn);

multi(2)(3)(4);
multi(2,3,4);
multi(2)(3,4);
multi(2,3)(4);
  1. 「中高级前端面试」JavaScript 手写代码无敌秘籍
  2. 实现一个 Promise 《图解 Promise 实现原理
// Promise 简单的实现
function APromise(fn) {
  const that = this;
  that.status = "pending"; // Promise初始状态为pending
  that.data = undefined; // Promise的值
  that.resCbs = []; // APromise resolve回调函数集合
  that.rejCbs = []; // APromise reject回调函数集合

  function resolve(data) {
    if (that.status === "pending") {
      that.status = "resolved";
      that.data = data;
      setTimeout(() => {
        that.resCbs.forEach((cb) => cb(data));
      });
    }
  }

  function reject(data) {
    if (that.status === "pending") {
      that.status = "rejected";
      that.data = data;
      setTimeout(() => {
        that.rejCbs.forEach((cb) => cb(data));
      });
    }
  }

  try {
    fn(resolve, reject); // 执行传进来的函数,传入resolve, reject参数
  } catch (e) {
    reject(e);
  }
}

APromise.prototype.then = function (onRes = (v) => v, onRej = (j) => j) {
  const that = this;

  if (that.status === "resolved") {
    // 这里promise的状态已经确定是resolved,所以调用onResolved
    return new APromise((resolve, reject) => {
      setTimeout(() => {
        try {
          // ret是onRes的返回值
          const ret = onRes(that.data);
          if (ret instanceof APromise) {
            // 如果ret是一个promise,则取其值作为新的promise的结果
            ret.then(resolve, reject);
          } else {
            // 否则,以它的返回值作为新的promise的结果
            resolve(ret);
          }
        } catch (e) {
          // 如果出错,以捕获到的错误作为promise2的结果
          reject(e);
        }
      });
    });
  }

  // 这里的逻辑跟前面一样,不再赘述
  if (that.status === "rejected") {
    return new APromise((resolve, reject) => {
      setTimeout(() => {
        try {
          const ret = onRej(that.data);
          if (ret instanceof APromise) {
            ret.then(resolve, reject);
          } else {
            reject(ret);
          }
        } catch (e) {
          reject(e);
        }
      });
    });
  }

  if (that.status === "pending") {
    // 如果当前的Promise还处于pending状态,则不能确定调用
    // onResolved还是onRejecte,只能等到Promise状态确定后,
    // 才能确定如何处理
    return new APromise((resolve, reject) => {
      that.resCbs.push(() => {
        setTimeout(() => {
          try {
            const ret = onRes(that.data);
            if (ret instanceof APromise) {
              ret.then(resolve, reject);
            } else {
              resolve(ret);
            }
          } catch (e) {
            reject(e);
          }
        });
      });

      that.rejCbs.push(() => {
        setTimeout(() => {
          try {
            const ret = onRej(that.data);
            if (ret instanceof APromise) {
              ret.then(resolve, reject);
            } else {
              reject(ret);
            }
          } catch (e) {
            reject(e);
          }
        });
      });
    });
  }
};

// 顺便实现一下catch方法
APromise.prototype.catch = function (onRej) {
  return this.then(null, onRej);
};

const p = new APromise(function (resolve, reject) {
  setTimeout(function () {
    resolve(1);
  }, 2000);
});

p.then(function (v) {
  console.log(v);
  return 2;
})
  .then(function (v) {
    console.log(v);
    return new APromise(function (resolve, reject) {
      setTimeout(function () {
        resolve(3);
      }, 3000);
    });
  })
  .then(function (v) {
    console.log(v);
  });


/**
 *实现promise中的all方法
 */
Promise.prototype.all = function (array) {
  judgeType(array);
  let count = 0;
  const total = array.length;
  const ret = [];
  return new Promise((resolve, reject) => {
    array.forEach((element) => {
      element.then((res) => {
        ret.push(res);
        count++;
        if (count === total) {
          resolve(ret);
        }
      });
      element.catch((err) => {
        reject(err);
      });
    });
  });
};
/**
 *类型的判断
 */
function judgeType(array) {
  if (array instanceof Array) {
    array.forEach((item) => {
      if (!(item instanceof Promise)) {
        throw "该参数的每一项必须是Promise的实例";
      }
    });
  } else {
    throw "必须是数组哦";
  }
}

var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
all = function (promises) {
  const total = promises.length;
  const ret = [];
  let count = 0;
  return new Promise((resolve, reject) => {
    promises.forEach((item) => {
      item.then((res) => {
        ret.push(res);
        count++;
        if (count === total) {
          return resolve(ret);
        }
      });
      item.catch((err) => {
        return reject(err);
      });
    });
  });
};
all([p1, p2, p3]).then(function (results) {
    //then方法不会被执行
    console.log(results);
}).catch(function (e){
    //catch方法将会被执行,输出结果为:2
    console.log(2);
});
/**
 *实现promise中的race方法
 */
Promise.prototype.race = function (promises) {
  return new Promise((resolve, reject) => {
    promises.forEach((item) => {
      Promise.resolve(item).then(
        (res) => {
          return resolve(res);
        },
        (err) => {
          return reject(err);
        }
      );
    });
  });
};
var p1 = new Promise(function (resolve, reject) {
  setTimeout(resolve, 500, "500");
});
var p2 = new Promise(function (resolve, reject) {
  setTimeout(resolve, 600, "600");
});
race([p1, p2]).then(function (result) {
  console.log(result); // '2018' 因为2018更快
});
/**
 *实现promise中的finally方法
 */
Promise.prototype.finally = function (onFinally) {
  return this.then(
    /* onFulfilled */
    (res) => Promise.resolve(onFinally()).then(() => res),
    /* onRejected */
    (err) =>
      Promise.resolve(onFinally()).then(() => {
        throw err;
      })
  );
};

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

//Promise 完整的实现
class Promise {
  callbacks = [];
  state = 'pending';//增加状态
  value = null;//保存结果
  constructor(fn) {
    fn(this._resolve.bind(this), this._reject.bind(this));
  }
  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      this._handle({
        onFulfilled: onFulfilled || null,
        onRejected: onRejected || null,
        resolve: resolve,
        reject: reject
      });
    });
  }
  catch(onError) {
    return this.then(null, onError);
  }
  finally(onDone) {
    if (typeof onDone !== 'function') return this.then();

    let Promise = this.constructor;
    return this.then(
      value => Promise.resolve(onDone()).then(() => value),
      reason => Promise.resolve(onDone()).then(() => { throw reason })
    );
  }
  static resolve(value) {
    if (value && value instanceof Promise) {
      return value;
    } else if (value && typeof value === 'object' && typeof value.then === 'function') {
      let then = value.then;
      return new Promise(resolve => {
        then(resolve);
      });

    } else if (value) {
      return new Promise(resolve => resolve(value));
    } else {
      return new Promise(resolve => resolve());
    }
  }
  static reject(value) {
    if (value && typeof value === 'object' && typeof value.then === 'function') {
      let then = value.then;
      return new Promise((resolve, reject) => {
        then(reject);
      });

    } else {
      return new Promise((resolve, reject) => reject(value));
    }
  }
  static all(promises) {
    return new Promise((resolve, reject) => {
      let fulfilledCount = 0
      const itemNum = promises.length
      const rets = Array.from({ length: itemNum })
      promises.forEach((promise, index) => {
        Promise.resolve(promise).then(result => {
          fulfilledCount++;
          rets[index] = result;
          if (fulfilledCount === itemNum) {
            resolve(rets);
          }
        }, reason => reject(reason));
      })

    })
  }
  static race(promises) {
    return new Promise(function (resolve, reject) {
      for (let i = 0; i < promises.length; i++) {
        Promise.resolve(promises[i]).then(function (value) {
          return resolve(value)
        }, function (reason) {
          return reject(reason)
        })
      }
    })
  }
  _handle(callback) {
    if (this.state === 'pending') {
      this.callbacks.push(callback);
      return;
    }

    let cb = this.state === 'fulfilled' ? callback.onFulfilled : callback.onRejected;

    if (!cb) {//如果then中没有传递任何东西
      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
      cb(this.value);
      return;
    }

    let ret;

    try {
      ret = cb(this.value);
      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
    } catch (error) {
      ret = error;
      cb = callback.reject
    } finally {
      cb(ret);
    }

  }
  _resolve(value) {
    if(this.state !== 'pending') return
    if (value && (typeof value === 'object' || typeof value === 'function')) {
      var then = value.then;
      if (typeof then === 'function') {
        then.call(value, this._resolve.bind(this), this._reject.bind(this));
        return;
      }
    }

    this.state = 'fulfilled';//改变状态
    this.value = value;//保存结果
    this.callbacks.forEach(callback => this._handle(callback));
  }
  _reject(error) {
    if(this.state !== 'pending') return
    this.state = 'rejected';
    this.value = error;
    this.callbacks.forEach(callback => this._handle(callback));
  }
}
目录
相关文章
|
存储 移动开发 前端开发
【React工作记录九十四】前端小知识点扫盲笔记记录3
【React工作记录九十四】前端小知识点扫盲笔记记录3
107 0
|
10月前
|
JavaScript
js事件记录(如有更新请留言我去补充)
js事件记录(如有更新请留言我去补充)
【博客项目】—用户修改功能(十一)
【博客项目】—用户修改功能(十一)
【博客项目】—用户删除功能(十二)
【博客项目】—用户删除功能(十二)
|
存储 缓存 移动开发
【React工作记录九十二】前端小知识点扫盲笔记记录
【React工作记录九十二】前端小知识点扫盲笔记记录
84 0
|
前端开发 JavaScript
【React工作记录九十五】前端小知识点扫盲笔记记录4
【React工作记录九十五】前端小知识点扫盲笔记记录4
84 0
|
域名解析 缓存 前端开发
【React工作记录一百】前端小知识点扫盲笔记记录5
【React工作记录一百】前端小知识点扫盲笔记记录5
74 0
|
负载均衡 Go
easycar更新日记
easycar更新日记
123 0
easycar更新日记
|
数据库 开发者 微服务
课程管理-修改章节 | 学习笔记
简介:快速学习课程管理-修改章节
124 0
课程管理-修改章节 | 学习笔记
|
开发者 微服务
课程管理-删除章节 | 学习笔记
简介:快速学习课程管理-删除章节
159 0
课程管理-删除章节 | 学习笔记