1.高阶函数:一个函数接受一个函数或者像闭包一样的返回一个函数; (函数的参数里面有函数)
function doSth(t,cb){
return function(){
if(--t===0){
cb();
}
}
}
function logSth(){
console.log('努力成为人上人')
}
let fn =doSth(3,logSth);
fn();
fn();
fn();
//在执行第三次的时候打印了
2.回调地狱
$.ajax({
success(data1){
$.ajax({
data:{d:data1},
success(data2){
data:{e:data2},
$.ajax({
....
})
}
})
}
})
ajax是异步请求
3.promise 承诺 (承诺实现 resolve(解决问题) 承诺石沉大海 reject 承诺等待结果中 pending)
promise解决异步流程化的一种手段 promise的目的
promise是一个构造函数 是需要new的
promise里面有且只有一个参数是excutor执行器
excutor有两个参数---> 一个是resolve 一个是reject ---->两个参数都是函数 都是可以执行的
excutor执行器是在new Promise的时候调用执行的
//excutor执行器是同步执行的(!Important)
let promise =new Pronise((resolve,reject)=>{
resolve('承诺实现');
//reject('承诺石沉大海')
});
//每个promise对象都有一个then方法 (then是异步的)
promise.then((res)=>{
console.log('Then')
console.log(res);//承诺实现
},(err)=>{
console.log(err);//只有在状态为reject的时候执行这个 承诺石沉大海
})
console.log('Gloabl')
//输出结果 (因为Then方法是异步的)
//1.Gloabl
//2.Then
//3.承诺实现
两个参数一个状态之间的关系
pending-->resolved 或
pending-->rejected 反过来是不行的 resolved <--->rejected 这两个执行之后的状态是不能够相互转换的
4.promise.all
用于多个异步任务并发运行,他的结果创建之后使用,等待所有任务结果的完成
Promise.all(iterable) iterable的数据类型必须是Array Map Set结构的
Promise.all([
1,true,'123'
]).then(res=>{
consoloe.log(res);//[1,true,'123']
})
//iterable内部传递的是promise对象集合,如果不是就直接resolve
//iterable内部没有元素 就返回空数组
//如果iterable中间的promise有一个rejected了 那就直接返回rejected
//如果iterable中间有多个失败 返回的始终是第一个失败的结果
Promise.resolve('成功啦')等价于下面 (语法糖)
new Promise((resolve,reject)=>{
resolve('成功啦')
})
Promise.reject('失败啦') 同理
new Promise((resolve,reject)=>{
reject('失败啦')
})
5.Promise.race
用于多个异步任务并发运行,谁先完成,就返回那个promise的结果 无论是fullfilled(成功完成状态)还是rejected
Promise.race(iterable) iterable的数据类型必须是Array Map Set结构的
如果iterable里面是空的,则不回返回,其状态永远都是pending状态
用的少 但是在测试资源响应速度或者接口响应的速度时可以用
6.async await
saync是一个异步函数 await就是一个操作符
async的意思是当前这个异步函数与同一作用域下的程序是异步关系
await就是一个等待Promise对象产出结果的操作手段 功能就是暂停async函数的执行,等待Promise处理后的结果
假如Promise处理的结果是rejected,会抛出异常
async 函数是通过一个隐式的Promise返回一个pending状态 有async必须有await 反之则可以
function getData0(){
return new Promise((resolve,reject)=>{
resolve('成功')
}).then((res)=>{
console.log(res)
},(err)=>{
console.log(err)
})
}
function getData1(){
return new Promise((resolve,reject)=>{
resolve('成功')
}).then((res)=>{
console.log(res)
}).catch(err)=>{
console.log(err)
}
}
...
async function logData(){
const p1=await getData0();
const p2=await getData1(p1);
const p3=await getData2(p2);
const p4=await getData3(p3);
return p4;
)
}
logData()
async 和await很好的解决了Promise的链式调用
7.Promise源码解析
promise.then(onFullfilled,onRejected) 这是两个状态 可以只写一个 也可以不写
先自己创建一个简单的promise
const PENDING = 'PENDING',
FULFILLED = 'FULFILLED',
REJECTED = 'REJECTED';
class MyPromise {
//传入的函数 在实例的时候constructor会立即执行
constructor(excutor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallBacks=[];
this.onRejectedCallBacks=[];
const resolve=(value) => {
if (this.status === PENDING) {
this.status === FULFILLED;
this.value = value;
//发布
this.onFulfilledCallBacks.forEach(fn=>fn());
}
}
const reject=(reason) => {
if (this.status === PENDING) {
this.status === REJECTED;
this.reason = reason;
//发布
this.onRejectedCallBacks.forEach(fn=>fn());
}
}
try {
excutor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
if (this.status === FULFILLED) {
onFulfilled(this.value);
}
if (this.status === REJECTED) {
onRejected(this.reason);
}
if(this.status===PENDING){
//订阅
this.onFulfilledCallBacks.push(()=>{
omFulfilled(this.value)
})
this.onRejectedCallBacks.push(()=>{
onRejected(this.reason)
})
}
}
}
export default MyPromise;
let promise=new myPromise((resolve,reject)=>{
resolve('success')
})
promise.then((value)=>{
console.log(value)
},(reason)=>{
console.log(reason)
})
链式调用
let promise=new Promise((resolve,reject)=>{
resolve('Resolve1')
})
)
//通过return传递结果
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
console.log(res);//Resolve1
})
//通过新的promise resolve结果
//第一种情况
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
return new Promise((resolve,reject)=>{
resolve(res)
})
}).then(res=>{
console.log(res);//Resolve1
})
//第二种情况
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
return new Promise((resolve,reject)=>{
setTomeout(()=>{
resolve(res);
},2000)
})
}).then(res=>{
console.log(res);//Resolve1
})
//第三种情况 通过新的promise reject去返回原因
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
return new Promise((resolve,reject)=>{
setTomeout(()=>{
reject('error');
},2000)
})
}).then(res=>{
console.log(res);
},err(err)=>{
console.log('reject'+err);//reject erroe
})
//第四种情况 then走了失败的回调之后再走then
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
return new Promise((resolve,reject)=>{
setTomeout(()=>{
reject('error');
},2000)
})
}).then(res=>{
console.log(res);
},err(err)=>{
console.log('reject'+err);//reject erroe
//默认return一个undefined
}).then(res=>{
console.log(res);//undefined
},err(err)=>{
console.log(err);
})
//第五种情况 then中使用了throw New Error
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
return new Promise((resolve,reject)=>{
setTomeout(()=>{
reject('error');
},2000)
})
}).then(res=>{
console.log(res);
},err(err)=>{
console.log('reject'+err);//reject erroe
//默认return一个undefined
}).then(res=>{
throw New Error('throw Error')
}).then(res=>{
console.log(res)
},err(reason)=>{
console.log('exception',reason);//exception Error:throw Error
})
//在Promise中使用try catch捕获异常 但是他回调用最近的失败函数
promise.then((res=>{
return res;//返回的是一个普通值
}).then(res=>{
return new Promise((resolve,reject)=>{
setTomeout(()=>{
reject('error');
},2000)
})
}).then(res=>{
console.log(res);
},err(err)=>{
console.log('reject'+err);//reject erroe
//默认return一个undefined
}).then(res=>{
throw New Error('throw Error')
}).then(res=>{
console.log(res)
},(reason)=>{
console.log('exception',reason);//exception Error:throw Error
}).catch(catch){
console.log('catch'+catch);
//这个的前提是上一个的error不存在 不然不会走到这个catch里面
return 'catch'+catch;
}.then(res=>{
console.log(res)//catch Error:throw Error
})
//catch在Promise的源码层就是一个then,Catch也是遵循then的运行原则的
//成功的条件
//then return 普通的javaScript value
//then return 新的promise成功态的结果 value
//失败的条件
//then return 新的promise失败态的原因 reason
//then 抛出异常 throw new Error
//promise的链式调用
//javascript JQuery retun this
//then不具备this
//return new Promise
注意区别
let promise=new Promise((resolve,reject)=>{....})
let promise2=promise.then(res=>{
return 'resolve' //第一次返回新的promise结果
}).then(res=>{
//return 第二次返回新的promise结果
})
let promise2=promise.then(res=>{
//return 第一次返回新的promise结果
})
promise2.then(res=>{
//return 第一次then返回新的promise结果
})
链式调用源码
let promise1=new Promise((reslove,reject)=>{
resolve('promise1');
})
let promise2=promise1.then(value=>{
//return Promise.resolve(value+'->then->promise2')
return value+'->then->promise2';//等同于上面
}).then(value=>{
console.log(value);//'promise1->then->promise2'
})
const PENDING = 'PENDING',
FULFILLED = 'FULFILLED',
REJECTED = 'REJECTED';
function resolvePromise = (promise2, x, resolve, reject) => {
console.log(promise2, x, resolve, reject);
if(promise2===x){
return reject(new TypeError('Chaining cycle detected for promise #<MyPromise>'))
}
let called=false;
if((typyof x==='Object' && x!==null) || typeof x ==='function'){
try{
let then =x.then;
if(typeof then ==='function'){//推断这是一个promise
then.call(x,(y)=>{
if(called)return;
called=true;
resolvePromise(promise2,y,resolve,reject)
},(r)=>{
if(called)return;
called=true;
reject(r)
})
}else{
resolve(x)
}
} catch(e){
if(called)return;
called=true;
reject(e)
}
} else{
resolve(x)
}
}
class MyPromise {
//传入的函数 在实例的时候constructor会立即执行
constructor(excutor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallBacks = [];
this.onRejectedCallBacks = [];
const resolve = (value) => {
if (this.status === PENDING) {
this.status === FULFILLED;
this.value = value;
//发布
this.onFulfilledCallBacks.forEach(fn => fn());
}
}
const reject = (reason) => {
if (this.status === PENDING) {
this.status === REJECTED;
this.reason = reason;
//发布
this.onRejectedCallBacks.forEach(fn => fn());
}
}
try {
excutor(resolve, reject)
} catch (e) {
reject(e)
}
}
//x 可能是普通值 也可能是promise
then(onFulfilled, onRejected) {
onFulfilled=typeof onFulfilled==='function'?onFulfilled:value=>value;
onRejected=typeof onRejected==='function'?onRejected:reason=>{throw reason}
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === PENDING) {
//订阅
this.onFulfilledCallBacks.push(() => {
try {
let x = omFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
this.onRejectedCallBacks.push(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
}
});
return promise2;
}
catch(errorCallback){
return this.then(null,errorCallback)
}
}
export default MyPromise;