js中A函数调用B函数,使用async/await的区别
背景,需要发起一个网络请求(setTimeout模拟),3秒得到结果。
要求必须在这个网路请求之后才能访问请求到的数据myRes。
要求调用方f4() 和 发起网络请求的f3()都必须用async/await。
假如f4()不用async/await,f3()用。代码执行到promise内部,执行完setTimeout加到宏任务-->输出“promise1000”,再遇见then加入到微任务。此时就跳出了await外部对应的async函数,继续执行同步代码"console.log(myRes+1);",这个时候myRes还没有有从网络获取到值“999”。
promise 3000 1 setTimeout 3000ms result 999 f3 最后一行
假如f4()用,f3()不用。
promise 3000 f3 最后一行 1 setTimeout 3000ms result 999
这两种情况在访问myRes的数值的时候“console.log(myRes+1);”,都还是原来的值“1”。
let myRes = 0;
async function f3() {// 模拟网络请求 console.log("f3"); let t=3000; await new Promise((res,rej)=>{ setTimeout(()=>{ console.log(`setTimeout ${t}ms`); res(999); } , t); console.log(`promise ${t}`); } ).then((result)=>{ myRes = result; console.log(`result ${result}`); } ); console.log("f3 最后一行") }; async function f4() { await f3(); console.log(myRes+1) } f4() // then后面部分需要等到前面promise执行完毕,才会加到queue // 在f4()中await后面紧跟的函数f3(),如果该函数f3()内部有promise: // 如果在f4()中,f4()想要f3()内部的promise和`console.log("f3 最后一行")`都执行结束过后,才执行await f3()的下一步" console.log(myRes+1)",那么f3()内的promise之前需要用await // 这种需求,f4()和f3()都需要用async/await
结果
f3 promise 3000 setTimeout 3000ms result 999 f3 最后一行 1000
1. tt()采用async/await,f()采用async/await.
会等到f()完全执行结束,才会输出“ffffffff”
console.log("code begin"); async function f() { console.log("f") await new Promise((res, rej) => { let t = 1000; setTimeout(() => { console.log(`setTimeout ${t}ms`); res(777); } , t); console.log(`promise ${t}`); }) .then((result) => { console.log(`result ${result}`) } ); console.log("f-2") } async function tt() { await f() console.log("ffffffff") } console.log("f1") tt(); console.log("code end"); // 1、tt()采用async/await,f()采用async/await. // 会等到f()完全执行结束,才会输出“ffffffff” // async function tt() { // await f() // console.log("fffffffff") // } /** f1 f promise 1000 code end setTimeout 1000ms result 777 f-2 ffffffff */
2. tt()不用(×)async/await,f()采用async/await。
tt()此时是同步代码,“ffffffff”会先于“code end”输出
console.log("code begin"); async function f() { console.log("f") await new Promise((res, rej) => { let t = 1000; setTimeout(() => { console.log(`setTimeout ${t}ms`); res(777); } , t); console.log(`promise ${t}`); }) .then((result) => { console.log(`result ${result}`) } ); console.log("f-2") } async function tt() { f() console.log("ffffffff") } console.log("f1") tt(); console.log("code end"); // 2、tt()不用(×)async/await,f()采用async/await。 // tt()此时是同步代码,“ffffffff”会先于“code end”输出 // async function tt() { // f() // console.log("ffffffff") // } /** f1 f promise 1000 ffffffff code end setTimeout 1000ms result 777 f-2 */
3. tt()采用async/await,f()不采用(×)async/await.
console.log("code begin"); async function f() { console.log("f") new Promise((res, rej) => { let t = 1000; setTimeout(() => { console.log(`setTimeout ${t}ms`); res(777); } , t); console.log(`promise ${t}`); }) .then((result) => { console.log(`result ${result}`) } ); console.log("f-2") } async function tt() { await f() console.log("ffffffff") } console.log("f1") tt(); console.log("code end"); // 3、tt()采用async/await,f()不采用(×)async/await. // 正确 // code begin // f1 // f // promise 1000 // f-2 // code end //因为Promise中用了setTimeout,“code end”输出后,不会执行setTimeout(宏任务)中的console,所以也不执行then(微任务)。 // (因为then必须等到Promise中所有内容执行完毕,setTimeout在Promise内部,所以then必须等到setTimeout执行完毕); // 那tt()采用了async/await(awwit f()),为什么不等到f()执行完毕呢? // 答:因为f()内部没有像第一点那样采用await Promise,其实f()已经执行完了,你看“f-2”都已经输出了。 // 如果Promise中没用用setTimeout,那么输出的情况将会是下面标记为【去掉setTimeout】的结果。 // ffffffff // setTimeout 1000ms // result 777 console.log("code begin"); async function f() { console.log("f") new Promise((res, rej) => { let t = 1000; // setTimeout(() => { // console.log(`setTimeout ${t}ms`); res(777); // } // , t); console.log(`promise ${t}`); }) .then((result) => { console.log(`result ${result}`) } ); console.log("f-2") } async function tt() { await f() console.log("ffffffff") } console.log("f1") tt(); console.log("code end"); // 【去掉setTimeout】 // code begin // f1 // f // promise 1000 // f-2 // code end // result 777 // ffffffff
4. tt()不采用(×)async/await,f()不采用(×)async/await.
console.log("code begin"); async function f() { console.log("f") new Promise((res, rej) => { let t = 1000; setTimeout(() => { console.log(`setTimeout ${t}ms`); res(777); } , t); console.log(`promise ${t}`); }) .then((result) => { console.log(`result ${result}`) } ); console.log("f-2") } async function tt() { f() console.log("ffffffff") } console.log("f1") tt(); console.log("code end"); // 4、tt()不采用(×)async/await,f()不采用(×)async/await. // code begin // f1 // f // promise 1000 // f-2 // ffffffff // code end // setTimeout 1000ms // result 777 // 注释掉setTimeout console.log("code begin"); async function f() { console.log("f") new Promise((res, rej) => { let t = 1000; // setTimeout(() => { // console.log(`setTimeout ${t}ms`); res(777); // } // , t); console.log(`promise ${t}`); }) .then((result) => { console.log(`result ${result}`) } ); console.log("f-2") } async function tt() { f() console.log("ffffffff") } console.log("f1") tt(); console.log("code end"); // code begin // f1 // f // promise 1000 // f-2 // ffffffff // code end // result 777
/**function f1() { asyncFunc() } async function f2() { await asyncFunc() } await f1() // 不会等待asyncFunc(),如果asyncFunc()返回rejection,直接触发 unhandledrejection await f2() // 会等待asyncFunc(),如果asyncFunc()返回rejection,会转回成错误并向上传播 链接:https://www.zhihu.com/question/462421951/answer/1916281835 */