本质缘由是JS须要交互,须要引入时间的概念。web
sync=同步,async=不一样步,字面意思跟实际执行状况正好相反。若是没有异步执行,则按照JS的代码一条一条line by line同步执行,执行的逻辑是event loop,即每条代码执行过程当中:若是在main thread上的代码则逐步执行,同步执行顺序参考: developer.mozilla.org/en-US/docs/… 优先级**(stack/script,microtask/promise,task/webapi)**api
若是要在执行中引入前后的顺序怎么办?好比先获取地理位置再才能计算距离长度。若是同步执行,则会发生错乱。好比地理位置api尚未返回回来,则开始了计算,会出现undefined的错误。promise
let location=getLoaction(api){
fetch(api);
}
//calCulateDistance
let distance= (location+32)*232/45;
console.log(distance);
复制代码
那么该怎么“同步”这些前后顺序的操做呢?即经过人工控制执行顺序。bash
#一. 以CallBack方法引入前后顺序#异步
fetch(api,(err,location)={
if(location) {
let distance= (location+32)*232/45;
console.log(distance);
};
})
复制代码
问题是:复杂的逻辑,会引发callback hell,并且把callback函数交由第三方fetch很差。async
#二. 以Promise方法引入前后顺序(须要改写CallBack)函数
getLoaction ()=>{
return new Promise((resolve, reject) =>{
fetch(api,(err,location)={
if(location) {
resolve(location)
}else{
reject(err)
};
})
})
复制代码
须要仔细理解的是:代码行碰到promise的时候即开始执行(按照原生的自带的顺序执行stack/microtask/task),轮到microtask的时候,promise已经开始执行,promise是一个已经存在的对象object,这个对象状态在按照内部逻辑更新而已,即pending->fullfilled(reject/resolve)。这个对象是一直存在的。这个对象的内部有一些监听器,then/catch,当对象状态变化时,则触发onThen监听器,其实也是调用咱们传入的CallBack函数而已!这样说来promise本质是方法一CallBack的不一样写法而已!!oop
3.关于then(其实就是CallBack函数,也叫then handler)返回的问题fetch
A.若是then返回return了ThenReturnedValue,则至关于返回一个Promise.resolve(),这个promise以供下一个then来使用consumeui
B.若是then返回了reject或者throw error,则Promise.reject()
C.若是then返回一个新的Promise,叫NewPromise,则NewPromise
then由于是CallBack,error first callback(实际上是error second callback),因此形式是:.then( resolveCallBackFun,rejectCallBackFun)
#三. 以Async Await方法引入前后顺序(改写Promise)
function resolveAfter2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 1000);
});
}
async function asyncCall() {
console.log('calling');
var result = await resolveAfter2Seconds();
console.log(result);
console.log('ending');
}
function promiseCall2() {
console.log('calling');
resolveAfter2Seconds().then((result)=>{
console.log(result);
});
console.log('ending');
}
asyncCall();//会hold住全部后面的;整个执行顺序仍是正常同步流程stack->microtask->task
> "calling"
> "resolved"
> "ending"
promiseCall2(); //只会hold then里面的;整个执行顺序仍是正常同步流程stack->microtask->task
> "calling"
> "ending"
> "resolved"
复制代码
2.关于async函数func返回的问题, 至关于.then callback, async函数返回也:
A.若是返回value,则async返回Promise.resolve()
B.若是返回NewPromise,则NewPromise
C.若是返回Error,则Promise.reject(),能够经过后续的try/catch捕获
D.若是没有return,则返回Promise.resolve(NULL)
3.async的小技巧IIF
(async () => {
try {
var text = await myPromise();
} catch (e) {
}
})();
复制代码
上面的论证被Mozilla再次证实!
重要文献:
jakearchibald.com/2015/tasks-…
developer.mozilla.org/en-US/docs/…