如何详细解释JavaScript中async和await的用法和原理?

摘要:async 函数永远会返回一个promise,即使你在函数中没有返回任何值。 async 函数永远会返回一个promise,即使你在函数中没有返回任何值。 因为:返回没有返回值时函数默认返回的是 undefined. 所以:会返回一个 pr
async 函数永远会返回一个promise,即使你在函数中没有返回任何值。 async 函数永远会返回一个promise,即使你在函数中没有返回任何值。 因为:返回没有返回值时函数默认返回的是 undefined. 所以:会返回一个 promise,这个 promise 的 值为 undefined。 async function doThingFn(){ console.log('doThingFn') } // async 函数永远会返回一个promise,即使你在函数中没有返回任何值。 console.log(111, doThingFn()) // 输出的值是 undefined // 因为async 函数会返回一个promise, 所以我们是可以写then的。 doThingFn().then(res=>{ console.log('输出的值是',res) }) async 函数的返回是Promise.resolve async function doThingFn(){ console.log('doThingFn') } 等于与下面的 async function doThingFn(){ // 返回没有返回值时函数默认返回的是 undefined. return Promise.resolve(undefined) } 当 await 遇到一个被拒绝的 Promise 时,它会抛出异常。因此需要被捕获 下面依次输出的结果是:A async function doThingFn(){ console.log('A') const result2 = await Promise.reject('B') console.log('C') return Promise.reject('D' ) } doThingFn() 为啥只会输出:A ? 因为当 await 遇到一个被拒绝的 Promise 时,它会抛出异常。我们没有捕获,直接就会报错的。 因此下面的 C 不会输出。 为啥不会输出 C async function doThingFn(){ try{ console.log('A') const result2 = await Promise.reject('B') console.log('C') }catch(err){ console.log('err',err) } } doThingFn() 分析:当 await 遇到被拒绝的 Promise 时(就是说:Promise.reject): 立即抛出异常,中断当前代码块的执行。 (如果有catch), 直接跳转到最近的 catch 块 await 之后的代码不会执行,因此不会输出 C。 如何让他输出C async function doThingFn(){ try{ console.log('A') // 我们在这里将它捕获掉。这样就可以输出C const result2 = await Promise.reject('B').catch(err=>{ console.log('err',err) }) console.log('C') }catch(err){ console.log('err',err) } } doThingFn() 如何在异步中正确获取到B的值 async function timeOutFn(){ setTimeout(()=>{ Promise.resolve('B') },5000) } async function doThingFn(){ console.log('A') // 如何让这里正确获取到B的值 const result2 = await timeOutFn() console.log(result2) } doThingFn() 上面的 await timeOutFn() 得到的值是什么?undefined timeOutFn 函数本身没有显式返回值,因此默认返回 undefined 下面这样就可以获取到值啦~~~ async function timeOutFn(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('B') },5000) }) } async function doThingFn(){ console.log('A') // return new Promise(...) 是 timeOutFn 函数的返回值 const result2 = await timeOutFn() console.log(result2) } doThingFn() 有的小伙伴会问: resolve('B') 为啥不需要return 因为: resolve 是一个回调函数,它用来改变 Promise 的状态从 "pending" 到 "fulfilled" 调用 resolve('B') 只是通知 Promise 完成,并传递值 'B' 给后续的 .then() 或 await return new Promise(...) 是 timeOutFn 函数的返回值 resolve('B') 是设置 Promise 的解析值,不是函数的返回值 下面 result2 的值是什么? async function timeOutFn(){ setTimeout(()=>{ return new Promise.resolve('B') },5000) } async function doThingFn(){ console.log('A') // result2 的值是什么? const result2 = await timeOutFn() console.log(result2) } doThingFn() 为啥result2 得到的值是 undefined 在这个函数中,我们使用了setTimeout,setTimeout本身是异步的。 但是它的回调函数是在5秒后执行的。 timeOutFn函数本身并没有等待这个setTimeout的回调函数,而是立即执行完毕。【这个是重点】 因为timeOutFn函数内部没有return语句。所以它返回的是一个undefined。 undefined会被Promise.resolve包装一下,即Promise.resolve(undefined)。 await 不能单独使用,需要配合async一起使用。 不要乱用await,因为 await 是基于 Promise 一起使用的(后面跟的是一个 Promise 对象) await 后面跟的是一个 Promise 对象,如果不是,则会通过 Promise.resolve()包裹一层 async function example() { const value1 = await 42; // 数字 → Promise.resolve(42) const value2 = await 'hello'; // 字符串 → Promise.resolve('hello') const value3 = await {data: 1}; // 对象 → Promise.resolve({data: 1}) const value4 = await null; // null → Promise.resolve(null) console.log(value1, value2, value3, value4); } example() async 和 await 的理解 #### async 和 await 的语法规则 1,async 函数永远会返回一个promise,即使你在函数中没有返回任何值。 2,async 是 function 的一个前缀,只有 async 函数中才能使用 await 语法 3,await 不能单独使用,需要配合async一起使用。 4,await 后面跟的是一个 Promise 对象,如果不是,则会通过 Promise.resolve()包裹一层 await和async的主要作用 await和async 主要是用来优化处理回调地狱的。