最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 你真的了解async...await吗?进来看看这道题

    正文概述 掘金(nikolausliu)   2021-07-14   572

    偶然间看到下面这道题,是考察async...await机制的,我觉得还挺有意思的。你可以试试不借助控制台自己在心里推算一下运行结果。

    const Err = async () => {
    	throw new Error(42);
    };
    
    const Obj = {
    	async A (){
    		try {
    			return Err();
    		} catch {
    			console.log('A');
    		}
    	},
    	async B (){
    		try {
    			await Err();
    		} catch {
    			console.log('B');
    		}
    	},
    	async C (){
    		try {
    			Err();
    		} catch {
    			console.log('C');
    		}
    	},
    };
    
    ( async () => {
    	for( const key in Obj )
    	{
    		try {
    			await Obj[key]();
    		} catch {
    			console.log('D');
    		}
    	}
    } )();
    

    放一张图片防止你们看到答案

    你真的了解async...await吗?进来看看这道题

    先说答案,分别打印DB,最后报错Uncaught (in promise) Error: 42

    我总结了一下,这题主要考察了以下知识点:

    async函数总是返回一个promise

    这个promise是什么,分为以下情况:

    1. 函数体内抛出了错误,则函数执行结果为这个错误的Promise.reject()包装对象
    2. 如果函数体内返回了一个promise,则函数执行结果就是这个promise。
    3. 否则,函数执行结果为函数体内返回值的Promise.resolve()包装对象。有一种情况容易让人混淆:函数体return new Erro(1),则执行结果相当于Promise.resolve(new Error(1)),注意return new Error(1)throw new Error(1)的区别。
    async function fn1() {
        throw new Error(1)
    }
    async function fn2() {
        return Promise.reject(1)
    }
    async function fn3() {}
    async function fn4() {
        return new Error(1)
    }
    fn1()   // Promise {<rejected>: Error: 1}
    fn2()   // Promise {<rejected>: 1}
    fn3()   // Promise {<fulfilled>: undefined}
    fn4()   // Promise {<fulfilled>: Error: 1}
    

    await在等待解开一个promise,等不来就报错

    上面的标题是为了简短一点,可能描述地不是很准确,我会拆分成几点来说明:

    1. await后总是跟一个promise,如果后面跟的不是promise,会用Promise.resolve()包装一下。
    2. 如果await表达式后跟一个fulfilled态的promise,会返回对应的值。
    3. 如果await表达式后跟一个rejected态的promise,会抛出错误,可以用.catch()方法try...catch块捕获。
    async function fn1() {
        const res = await Promise.resolve(1)
        console.log(res)
    }
    async function fn2() {
        const res = await new Error(1) // 相当于Promise.resolve(new Error(1))
        console.log(res)
    }
    async function fn3() {
        const res = await Promise.reject(1)
        console.log(res)    
    }
    fn1()   // 1
    fn2()   // Error: 1
    fn3()   // 报错 Uncaught (in promise) 1
    // fn3改写成下面两种形式都能捕获错误
    async function fn3() {
        const res = await Promise.reject(1).catch(e => {
            console.log(e)
        })
    }
    async function fn3() {
        try {
            const res = await Promise.reject(1)   
        } catch(e) {
            console.log(e)
        }
    }
    

    了解了上面的知识点,我们就可以分析代码了,我把代码解释放在了下面的代码注释中,这样看起来应该更清晰一点:

    const Err = async () => {
    	throw new Error(42);
    	// 相当于 return Promise.reject(new Error(42))
    };
    
    const Obj = {
    	async A (){
    	    // 1.2 for循环中`await A()`相当于`await Promise.reject(new Error(42))`
    	    // 会被for循环内的catch块捕获
    	    // **所以第1轮for循环输出D**
    		try {
    			return Err();
    			// 1.1 相当于 return Promise.reject(new Error(42))
    			// 这行代码没有抛出错误,所以下面的catch块不会走,不会输出A
    		} catch {
    			console.log('A');
    		}
    	},
    	async B (){
    	    // 2.2 for循环中`await B()`相当于`await Promise.resolve(undefined)`
    	    // 这行代码不会被for循环内的catch块捕获
    	    // **所以第2轮for循环输出B**
    		try {
    		    // 2.1 相当于`await Promise.reject(new Error(42))`
    		    // 这行代码会被下面的catch块捕获,输出B
    			await Err();
    		} catch {
    			console.log('B');
    		}
    	},
    	async C (){
    	    // 3.2 for循环中`await C()`相当于`await Promise.resolve(undefined)`
    	    // 不会被for循环内的catch块捕获
    	    // **所以第3轮什么都不输出。但是会报错`Uncaught (in promise) Error: 42`**
    		try {
    		    // 3.1 相当于`Promise.reject(new Error(42))`
    		    // 这行代码不会被下面的catch块捕获,不会输出C
    		    // 但是由于这个`rejected`态的promise没有被catch处理所以会报错`Uncaught (in promise) Error: 42`
    		    // 注意try...catch块内`Promise.reject()`和`await Promise.reject()`是不一样的。
    			Err();
    		} catch {
    			console.log('C');
    		}
    	},
    };
    
    ( async () => {
    	for( const key in Obj )
    	{
    		try {
    			await Obj[key]();
    		} catch {
    			console.log('D');
    		}
    	}
    } )();
    

    起源地下载网 » 你真的了解async...await吗?进来看看这道题

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元