(1)promise
1:实现原理
主要是通过回调函数来实现,内部封装了回调函数,通过then方法链式调用,将异步的代码以同步的形式表现出来。
2:promise的特点
状态只有三种:等待,成功,失败
状态的改变只能改变一次
3:promise的缺点
一旦执行不能取消,出现错误要通过回调函数捕获
4:promis构造函数调用和promise的链式调用的区别
构造函数的调用是立即执行的
new Promise((resolve, reject) => {
console.log('new Promise')
resolve('success')
})
console.log('finifsh')
// new Promise -> finifsh
Promise实现了链式调用,也就是说每次调用
then之后返回的都是一个
Promise,并且是一个全新的
Promise,原因也是因为状态不可变。如果你在
then中 使用了
return,那么
return的值会被
Promise.resolve()` 包装
Promise.resolve(1)
.then(res => {
console.log(res) // => 1
return 2 // 包装成 Promise.resolve(2)
})
.then(res => {
console.log(res) // => 2
})
5:promise的实现
function myPromise(excus)
{
let that=this;
//记录当前的状态
that.state="pending";
//成功的值
that.value=null;
//失败的原因
that.rean=null;
//暂存区用来解决异步任务
that.resolvedCallbacks = [];
that.rejectedCallbacks = [];
//改变成功的状态
function resovle(value)
{
if(that.state=='pending')
{
that.state="Resolve";
that.value=value;
that.resolvedCallbacks.forEach(item=>{
item(value);
})
}
}
//改变失败的状态
function reject(value)
{
if(that.state=='pending')
{
that.state='Reject';
that.rean=value;
that.rejectedCallbacks.forEach(item=>{
item(rean);
})
}
}
//立即执行
excus(resovle,reject);
}
//then
myPromise.prototype.then=function(resovle,reject){
//解决异步调用
that=this;
resovle =typeof resovle ==='function'?resovle:function(data){
return data;
}
reject =typeof reject ==='function'?reject:function(err){
throw err;
}
if(that.state=='pending')
{
that.resolvedCallbacks.push(resovle);
that.rejectedCallbacks.push(reject);
}
return new myPromise((onfullfilled,Onreject)=>{
if(that.state==='Resolve')
{
try{
x=onfullfilled(that.value);
console.log(x);
resovle(x);
}catch(e){
reject(e);
}
}
})
}
var p=new myPromise((resovle,reject)=>{
setTimeout(() => {
resovle('123');
}, 1000);
});
p.then((result) => {
console.log(result);
},(err) => {
console.log(err);
});
//promise实现异步用发布者订阅模式
6:promiseall的实现
function promiseAll(Promises)
{
return new Promise(function(resolve,reject){
if(!Array.isArray(Promises))
{
return reject(new TypeError("argument"));
}
var countNum=0;
var promiseNum=Promises.length;
var resolvedvalue=new Array(promiseNum);
for(let i=0;i<promiseNum;i++)
{
Promise.resolve(Promises[i]).then(function(value){
countNum++;
resolvedvalue[i]=value;
if(countNum===promiseNum)
{
return resolve(resolvedvalue);
}
},function(reason){
return reject(reason);
})
}
})
}
var p1=Promise.resolve(1),
p2=Promise.resolve(2),
p3=Promise.resolve(3);
promiseAll([p1,p2,p3]).then(function(value){
console.log(value)
})
(2):async 及 await
1:async 函数
它会返回一个promise对象,通过promise.resolve()进行封装
2:await和async配套使用
优点:和promise进行比较,处理了then的链式调用,更加的简洁
缺点:就是在没有依赖情况下,会导致性能的降低。在没有依赖关系的时候使用promise.all()效率更高一些。
await的实现原理:
主要是promise语法糖和生成器的结合,await通过生成器实现,保存当前堆栈中的信息,当执行异步代码的时候读取堆栈中的信息和返回过来的promise对象结合
生成器
当我们实例化一个生成器的时候,会返回一个迭代器Iterator。
然后通过yield/next控制代码的执行顺序,当我们执行yield的时候生成器函数内部暂停代码的执行,生成器的外部还是活跃的状态,内部的资源保留了下来,只不过是处在暂停状态。
当我们执行next的时候,会从暂停的位置开始执行。
为什么next比yield要多一个?
因为当我们实例化生成器以后,代码是不会立即执行的,要通过next启动生成器,后面的yield和next进行一个对应。所以next要比yield多一个。