1.前端异步处理的方式有:
- 回调函数的方式( 事件监听的方式, 事件订阅)
- Promise的方式
- Genrator的方式
- Async/Await
js单线程-->出现异步-->通过回调函数解决异步-->出现回调地狱-->出现promise的链式调用解决回调地狱-->Genrator->async/await
2. Genrator(我们先讲它):
Generator返回值是一个指针(遍历器),这是Generator函数不同于其它函数的地方,执行它不会返回明确的结果,而是返回一个指针对象。调用指针对象的next方法,会移动内部的指针(执行任务的第一段),指向第一个遇到的yield语句(暂停),返回yield后面的表达式的值。
咋说呢,这玩意有点奇怪,第一是它函数名声明的前边必须带上一个*号,然后其中如果想有异步操作就需要通过yield进行标识,最后容器返回的对象是一个迭代器对象,通过调用迭代器对象的 next()
方法,我们可以逐步获取生成器函数中 yield
关键字生成的下一个值。每次调用 next()
方法时,生成器函数会从上一次暂停的位置继续执行,直到遇到下一个 yield
关键字或函数结束。其中next传入的值就是上一个yield语句返回值的结果,就比如说这个函数刚进去的时候是x=5,然后第一个next结束返回value=6,然后第二次调用了next方法,传入了12也就是说y=2*12,相当于第一个yield表达式x+1直接被赋值为12,接着也是如此...
3.promise的实现方式
//Promise有三种状态,一旦处于某种状态之后将不再改变
const PROMISE_PENDING = "PENDING";
const PROMISE_FULLFIEELD = "FULLFIEELD";
const PROMISE_REJECTED = "REJECTED";
//创建类
class MyPromise {
constructor(executor) {
//初始化状态
this.status = PROMISE_PENDING;
this.result = undefined;
this.error = undefined;
this.resFn = [];
this.errFn = [];
//定义两个函数,resolve,reject
const resolve = (result) => {
//判断状态,只有为pending的时候才执行
if (this.status === PROMISE_PENDING) {
this.status = PROMISE_FULLFIEELD;
//执行then中的回调,这个时候需要添加到异步队列中,否则就会出现为定义,因为先执行的resolve,再调用的then方法
this.result = result;
queueMicrotask(() => {
this.resFn.forEach((fn) => {
fn(this.result);
});
});
}
};
const reject = (error) => {
if (this.status === PROMISE_PENDING) {
this.status = PROMISE_REJECTED;
this.error = error;
//执行then中的回调
queueMicrotask(() => {
this.errFn.forEach((fn) => {
fn(this.error);
});
});
}
};
//Promise内部函数是同步执行的,所以立即执行executor,并传入resolve和reject
executor(resolve, reject);
}
//因为可以通过.then的方式调用,因此实例需要有then方法,并接受两个回调函数,第一个为成功时候的回调,第二个为失败时候的回调
then(resFn, errFn) {
// 如果使用这种直接赋值的话就会导致无法多次调用.then方法,因为当同时调用两次.then方法的时候,因为是同步代码所以后边的会将前边的值覆盖
// this.resFn = resFn;
// this.errFn = errFn;
//返回MyPromise就可以采用链式调用了
return new MyPromise((resolve, reject) => {
//当处于不同的状态下面,采取不同的操作
if (this.status === PROMISE_FULLFIEELD && resFn) {
//拿到上个MyPromise的resolve值,并将这个resFn的返回值传入
try {
const result = resFn(this.result);
resolve(result);
} catch (err) {
reject(err);
}
}
if (this.status === PROMISE_REJECTED && errFn) {
try {
const error = errFn(this.error);
resolve(error);
} catch (err) {
reject(err);
}
}
if (this.status === PROMISE_PENDING) {
//那么如何做到同时调用多个呢,,也就可以采用数组的方式
this.resFn.push(() => {
try {
const result = resFn(this.result);
resolve(result);
} catch (err) {
reject(err);
}
});
this.errFn.push(() => {
try {
const error = errFn(this.error);
resolve(error);
} catch (err) {
reject(err);
}
});
}
});
}
}
promise的实现方式我就不过多讲解了,其实也就是根据功能一步一步的去实现,大家不要看着复杂,只要一个一个功能点去实现的话也就非常清晰了。
4.Async/Await的实现方式就是结合了Genrator以及promise,从而达到异步的效果.