赞
踩
综述:手写一下,加深对知识的理解
- // 判断变量否为function
- const isFunction = variable => typeof variable === 'function'
- // 定义Promise的三种状态常量
- const PENDING = 'PENDING'
- const FULFILLED = 'FULFILLED'
- const REJECTED = 'REJECTED'
-
- class MyPromise {
- constructor (handle) {
- if (!isFunction(handle)) {
- throw new Error('MyPromise must accept a function as a parameter')
- }
- // 添加状态
- this._status = PENDING
- // 添加状态
- this._value = undefined
- // 添加成功回调函数队列
- this._fulfilledQueues = []
- // 添加失败回调函数队列
- this._rejectedQueues = []
- // 执行handle
- try {
- handle(this._resolve.bind(this), this._reject.bind(this))
- } catch (err) {
- this._reject(err)
- }
- }
- // 添加resovle时执行的函数
- _resolve (val) {
- const run = () => {
- if (this._status !== PENDING) return
- // 依次执行成功队列中的函数,并清空队列
- const runFulfilled = (value) => {
- let cb;
- while (cb = this._fulfilledQueues.shift()) {
- cb(value)
- }
- }
- // 依次执行失败队列中的函数,并清空队列
- const runRejected = (error) => {
- let cb;
- while (cb = this._rejectedQueues.shift()) {
- cb(error)
- }
- }
- /* 如果resolve的参数为Promise对象,则必须等待该Promise对象状态改变后,
- 当前Promsie的状态才会改变,且状态取决于参数Promsie对象的状态
- */
- if (val instanceof MyPromise) {
- val.then(value => {
- this._value = value
- this._status = FULFILLED
- runFulfilled(value)
- }, err => {
- this._value = err
- this._status = REJECTED
- runRejected(err)
- })
- } else {
- this._value = val
- this._status = FULFILLED
- runFulfilled(val)
- }
- }
- // 为了支持同步的Promise,这里采用异步调用
- setTimeout(run, 0)
- }
- // 添加reject时执行的函数
- _reject (err) {
- if (this._status !== PENDING) return
- // 依次执行失败队列中的函数,并清空队列
- const run = () => {
- this._status = REJECTED
- this._value = err
- let cb;
- while (cb = this._rejectedQueues.shift()) {
- cb(err)
- }
- }
- // 为了支持同步的Promise,这里采用异步调用
- setTimeout(run, 0)
- }
- // 添加then方法
- then (onFulfilled, onRejected) {
- const { _value, _status } = this
- // 返回一个新的Promise对象
- return new MyPromise((onFulfilledNext, onRejectedNext) => {
- // 封装一个成功时执行的函数
- let fulfilled = value => {
- try {
- if (!isFunction(onFulfilled)) {
- onFulfilledNext(value)
- } else {
- let res = onFulfilled(value);
- if (res instanceof MyPromise) {
- // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
- res.then(onFulfilledNext, onRejectedNext)
- } else {
- //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
- onFulfilledNext(res)
- }
- }
- } catch (err) {
- // 如果函数执行出错,新的Promise对象的状态为失败
- onRejectedNext(err)
- }
- }
- // 封装一个失败时执行的函数
- let rejected = error => {
- try {
- if (!isFunction(onRejected)) {
- onRejectedNext(error)
- } else {
- let res = onRejected(error);
- if (res instanceof MyPromise) {
- // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
- res.then(onFulfilledNext, onRejectedNext)
- } else {
- //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
- onFulfilledNext(res)
- }
- }
- } catch (err) {
- // 如果函数执行出错,新的Promise对象的状态为失败
- onRejectedNext(err)
- }
- }
- switch (_status) {
- // 当状态为pending时,将then方法回调函数加入执行队列等待执行
- case PENDING:
- this._fulfilledQueues.push(fulfilled)
- this._rejectedQueues.push(rejected)
- break
- // 当状态已经改变时,立即执行对应的回调函数
- case FULFILLED:
- fulfilled(_value)
- break
- case REJECTED:
- rejected(_value)
- break
- }
- })
- }
- // 添加catch方法
- catch (onRejected) {
- return this.then(undefined, onRejected)
- }
- // 添加静态resolve方法
- static resolve (value) {
- // 如果参数是MyPromise实例,直接返回这个实例
- if (value instanceof MyPromise) return value
- return new MyPromise(resolve => resolve(value))
- }
- // 添加静态reject方法
- static reject (value) {
- return new MyPromise((resolve ,reject) => reject(value))
- }
- // 添加静态all方法
- static all (list) {
- return new MyPromise((resolve, reject) => {
- /**
- * 返回值的集合
- */
- let values = []
- let count = 0
- for (let [i, p] of list.entries()) {
- // 数组参数如果不是MyPromise实例,先调用MyPromise.resolve
- this.resolve(p).then(res => {
- values[i] = res
- count++
- // 所有状态都变成fulfilled时返回的MyPromise状态就变成fulfilled
- if (count === list.length) resolve(values)
- }, err => {
- // 有一个被rejected时返回的MyPromise状态就变成rejected
- reject(err)
- })
- }
- })
- }
- // 添加静态race方法
- static race (list) {
- return new MyPromise((resolve, reject) => {
- for (let p of list) {
- // 只要有一个实例率先改变状态,新的MyPromise的状态就跟着改变
- this.resolve(p).then(res => {
- resolve(res)
- }, err => {
- reject(err)
- })
- }
- })
- }
- finally (cb) {
- return this.then(
- value => MyPromise.resolve(cb()).then(() => value),
- reason => MyPromise.resolve(cb()).then(() => { throw reason })
- );
- }
- }
-
- Function.prototype.bind = function(oThis) {
- if (typeof this !== 'function') {
- // closest thing possible to the ECMAScript 5
- // internal IsCallable function
- throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
- }
-
- var aArgs = Array.prototype.slice.call(arguments, 1),
- fToBind = this,
- // 空函数
- fNOP = function() {},
- fBound = function() {
- return fToBind.apply(this instanceof fNOP
- ? this
- : oThis,
- // 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
- aArgs.concat(Array.prototype.slice.call(arguments)));
- };
-
- // 维护原型关系
- if (this.prototype) {
- // Function.prototype doesn't have a prototype property
- fNOP.prototype = this.prototype;
- }
- fBound.prototype = new fNOP();
-
- return fBound;
- };
- // 测试
- function foo(name) {
- this.name = name;
- }
- var obj = {};
- var bar = foo.myBind(obj);
- bar('Jack');
- console.log(obj.name); // Jack
- var alice = new bar('Alice');
- console.log(obj.name); // Jack
- console.log(alice.name); // Alice
- function Person (data) {
- console.log(data, 'person')
- }
- function children(data) {
- console.log(data,'children')
- }
- Function.prototype.myCall = function(context, ...args){
- if(typeof this !== 'function'){
- throw new TypeError(`${this} is not a function`);
- }
- // 如果没有传或传的值为空对象 context指向window
- context = context || window;
- context.fn = this;
- const result = context.fn(args.join());
- delete context.fn; //在使用完之后,删除这个方法
- return result; //如果有返回值,将其进行返回
- }
- Person.myCall(children,77777,8888) //7777,8888
4.js实现apply?
- function Person (data) {
- console.log(data, 'person')
- }
- function children(data) {
- console.log(data,'children')
- }
- Function.prototype.myApply = function(context, args){
- if(typeof this !== 'function'){
- throw new TypeError(`${this} is not a function`);
- }
- if(!Array.isArray(args)){
- throw new TypeError(`${args} is not a Array`);
- }
- context = context || window;
- context.fn = this;
- const result = context.fn(args);
- delete context.fn;
- return result;
- }
- Person.myApply(children,[77777,8888])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。