-
本质原因是JS需要交互,需要引入时间的概念。
-
sync=同步,async=不同步,字面意思跟实际执行情况正好相反。如果没有异步执行,则按照JS的代码一条一条line by line同步执行,执行的逻辑是event loop,即每条代码执行过程中:如果在main thread上的代码则逐步执行,同步执行顺序参考: developer.mozilla.org/en-US/docs/… 优先级**(stack/script,microtask/promise,task/webapi)**


- 既然JS正常是同步执行,为何要引入异步的概念?异步的引入是为了“同步”操作流程!
如果要在执行中引入先后的顺序怎么办?比如先获取地理位置再才能计算距离长度。如果同步执行,则会发生错乱。比如地理位置api还没有返回回来,则开始了计算,会出现undefined的错误。
let location=getLoaction(api){
fetch(api);
}
//calCulateDistance
let distance= (location+32)*232/45;
console.log(distance);
那么该怎么“同步”这些先后顺序的操作呢?即通过人工控制执行顺序。
#一. 以CallBack方法引入先后顺序#
fetch(api,(err,location)={
if(location) {
let distance= (location+32)*232/45;
console.log(distance);
};
})
问题是:复杂的逻辑,会引起callback hell,而且把callback函数交由第三方fetch不好。
#二. 以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的不同写法而已!!

- Promise的状态在microtask完成后才能改变,如果要获取改变后的值,则需要then,不然promise只是一个带状态的object

- 如果修改一下,则发现如下结果,因为microtask运行按照queue来的

3.关于then(其实就是CallBack函数,也叫then handler)返回的问题
A.如果then返回return了ThenReturnedValue,则相当于返回一个Promise.resolve(),这个promise以供下一个then来使用consume
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)
- Async其实是promise+generator(本质是promise), await就是相当于把promise .then了一下(当然error是通过try catch获取,类似then/catch),跟promise区别是会把后面的全部暂停住,相当于wrap到then里面。如图
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/…