js源码实现
简单实现Promise
js
// 未添加异步处理等其他边界情况
// ①自动执行函数,②三个状态,③then
class Promise2{
constructor(fn){
this.state = 'pendding' // 设置一个状态;
this.value = undefined // 这个用来接收参数;
let resolve = value =>{
this.state = 'resolve' // 给state赋值,改变状态,用来then方法判断使用;
this.value = value
}
let reject = value =>{
this.state = 'reject'
this.value = value
}
try{
fn(resolve,reject) //给传参的函数来两个形参,分别调用两个函数;
}catch(e){
reject(e)
}
}
then(resolve,reject){
if(this.state === 'resolve'){
resolve(this.value)
} else if(this.state === 'reject') {
reject(this.value)
}
}
}
实现一个call
改变this指针的call和apply的本质就是,将调用的函数放到传入的对象身上,此时this自动就变成对象本身了,之后执行完成将结果返回,删除放到对象身上的函数;
js
Function.prototype.myCall = function(context){
context = Object(context) || window //原生的this会自动用object()转换,不传参数或者null指向window;
context.fn = this //设定一个fn到传入的对象身上; this取的是函数;
let args = [...arguments].slice(1) //第一个是this对象,得隔离,这里是用来传参;
let result = context.fn(...args) //调用call时会执行; 这里将所有代码执行,并保存结果;
delete context.fn //执行完成就手动删除该函数;
return result //将执行结果返回;
}
实现一个apply
js
// apply就是传参问题,是数组
Function.prototype.myApply = function(context,args){
context = Object(context) || window
context.fn = this
//解决没有传参情况;
let result = args ? context.fn(...args) : context.fn()
delete context.fn
return result
}
实现一个bind
bind返回的绑定函数也能使用new操作符创建对象,这种行为就像把原函数当成构造器,bind与call/apply最大的不同就是前者返回一个绑定上下文的函数,而后两者是直接执行了函数
bind可以指定this,返回一个函数,可以传入参数,并且可以柯里化
定时器可以直接改变this指向:
js
setTimeout(function(){}.bind(this),500) //将this指向上文
Function.prototype.myBind = function(context){
//判断不是函数的传入情况;
if(typeof this !== 'function') throw new Error('error')
var that = this //保留this指向函数;
var args = [...arguments].slice(1) //获取传入的参数;
return function F(){
//因为返回的函数可以进行new,因此需要判断一下;判断this是否是指向F
if(this instanceof F) return new that(...args,...arguments)
// 返回调用的函数;
return that.apply(context,args.concat(...arguments))
}
}
实现async/await
js
function asyncToGenerator(generatorFunc) {
return function() {
const gen = generatorFunc.apply(this, arguments)
return new Promise((resolve, reject) => {
function step(key, arg) {
let generatorResult
try {
generatorResult = gen[key](arg)
} catch (error) {
return reject(error)
}
const { value, done } = generatorResult
if (done) {
return resolve(value)
} else {
return Promise.resolve(value).then(val => step('next', val), err => step('throw', err))
}
}
step("next")
})
}
}
Promise.all 简易版
js
Promise.all = function (iterators) {
return new Promise((resolve, reject) => {
if (!iterators || iterators.length === 0) {
resolve([]);
} else {
let count = 0; // 计数器,用于判断所有任务是否执行完成
let result = []; // 结果数组
for (let i = 0; i < iterators.length; i++) {
// 考虑到iterators[i]可能是普通对象,则统一包装为Promise对象
Promise.resolve(iterators[i]).then(
(data) => {
result[i] = data; // 按顺序保存对应的结果
// 当所有任务都执行完成后,再统一返回结果
if (++count === iterators.length) {
resolve(result);
}
},
(err) => {
reject(err); // 任何一个Promise对象执行失败,则调用reject()方法
return;
}
);
}
}
});
};
Promise.race 简易版
js
Promise.race = function (iterators) {
return new Promise((resolve, reject) => {
for (const iter of iterators) {
Promise.resolve(iter)
.then((res) => {
resolve(res);
})
.catch((e) => {
reject(e);
});
}
});
};