知识点

89 阅读2分钟

关于pormise

promise是异步的一种解决方式,本质为构造函数,其包含有all,reject,resolve等方法,究其原型,还包括then,catch方法。Promise包含有两大特点:其一,对象的状态不受外界的影响,其有三种状态,即pending(进行中)、fulfilled(已成功)和rejected(已失败),只有异步操作的结果可以决定的当前的状态;其二,状态改变就定型,即pending变为fulfilled和从pending变为rejected,只要发生这两种改变,就再也不会改变了。

pormise 是一种异步编程解决方案,里面保存未来才会结束的事件。
有两个特点:
1.状态不受外界影响,过程三种状态 pending fulfilled rejected
2.状态一但改变不会再变,可以以同步的流程表达出来避免了层层嵌套的回调函数

function ajax (url) {
  return new Promise((resolve, rejects) => {
    // 创建一个XMLHttpRequest对象去发送一个请求
    const xhr = new XMLHttpRequest()
    // 先设置一下xhr对象的请求方式是GET,请求的地址就是参数传递的url
    xhr.open('GET', url)
    // 设置返回的类型是json,是HTML5的新特性
    // 我们在请求之后拿到的是json对象,而不是字符串
    xhr.responseType = 'json'
    // html5中提供的新事件,请求完成之后(readyState为4)才会执行
    xhr.onload = () => {
      if(this.status === 200) {
        // 请求成功将请求结果返回
        resolve(this.response)
      } else {
        // 请求失败,创建一个错误对象,返回错误文本
        rejects(new Error(this.statusText))
      }
    }
    // 开始执行异步请求
    xhr.send()
  })
}

ajax('/api/user.json').then((res) => {
  console.log(res)
}, (error) => {
  console.log(error)
})

call 实现

// call 实现
Function.prototype.myCall = function(context) {
  context = context || window; // 默认 window
  const args = [...arguments].slice(1); // 参数
  const fn = Symbol(); // 给 context 设置一个独一无二的属性,避免覆盖原有属性
  context[fn] = this; // 这里的 this 指向调用它的函数 fn
  const result = context[fn](...args); // 调用之
  delete context[fn]; // 删除添加的属性
  return result; // 返回值
}

say.myCall(obj, '咿呀咿呀哟', '呱呱!') // 我是一只小鸭子,咿呀咿呀哟,呱呱!

apply 实现

// apply 实现
Function.prototype.myApply = function(context, args) {
  context = context || window; // 默认 window
  args = [...args]; // 参数
  const fn = Symbol(); // 给 context 设置一个独一无二的属性,避免覆盖原有属性
  context[fn] = this; // 这里的 this 指向调用它的函数fn
  const result = context[fn](...args); // 调用之
  delete context[fn]; // 删除添加的属性
  return result; // 返回值
}

say.myApply(obj, ['咿呀咿呀哟', '呱呱!']) // 我是一只小鸭子,咿呀咿呀哟,呱呱! 

bind 实现

// bind 实现
Function.prototype.myBind = function(context) {
  context = context || window; // 默认 window
  const args = [...arguments].slice(1); // 参数
  const fn = this; // 这里的 this 指向调用它的函数 fn
  return function () {
    return fn.apply(context, args);
  };
}

const manualSay = say.myBind(obj, '咿呀咿呀哟', '呱呱!');
manualSay(); // 手动执行,输出:我是一只小鸭子,咿呀咿呀哟,呱呱! 
  1. 绑定上下文 context
  2. 处理好参数 arguments
  3. 使用 Symbol 存储临时函数

实现一个new

function myNew(Func, ...args) {
  let obj = {};
  obj.__proto__ = Func.proto;
  let res = Func.apply(obj, args);
  return res instanceof Object ? res : obj;
}