要是实在不知道要干什么,那就喝两杯思路就来了!

导航菜单

async await 烧脑题

今天偶然间遇到一道烧脑题,顺手把它记录下来,研究研究下面代码控制台输出顺序是什么样子的?哈哈,已脱一层白发……%T

在上菜之前先补充一下 async 和 await 的使用场景,要不然就歇顶了哈。

function fetchData () {
	return new Promise(function (resolve, reject) {
		// 对不住了,就喜欢使用原生原味的异步执行方式
		var xhr = new XMLHttpRequest();
		xhr.open('GET', 'https://www.snrthn.com/edu/api.php/shop?transform=1', true);
		xhr.send();	
		xhr.onreadystatechange = function () {
			if (xhr.readyState === 4) {
				if (xhr.status === 200 || xhr.status === 304) {
					resolve();
				} else {
					reject();
				}
			}
		}
	})
}

async function demo () {
	await fetchData().then(function () {
		// 原本的异步代码是写在这里的
		console.log('请求成功!');
	}).catch(function () {
		// 或者也可以在这里异步
		console.log('请求凉凉了!');
	})

	// 但是现在我可以像同步方式一样写异步代码了
	console.log('我已经被当作回调代码了');
}

// 函数将在这里被触发
demo();

在使用 async 和 await 必须要注意的一个问题,那就是必须将要执行的异步代码块和回调代码放在一个函数的封闭作用域中否则即不报错也不会出效果。代码输出结果将会是 1、请求成功/失败;2、我已经被当作回调代码了;由此不难看出来,之前我们经历的回调地狱,在此就可以挥一挥衣衫,不带走一片云彩……

好了,重头戏就在下面,PS:在研究之前先买一筒焗油膏吧

(function () {
    var demo = async function () {
        console.log(1); // ㈠
        await new Promise(function (resolve, reject) {
            console.log(1.5); // ㈡
            setTimeout(async function () {
                console.log('promise1'); // ㈤
                let aa = '';
                await fetch('https://www.snrthn.com/edu/api.php/shop').then(function (res) {
                    console.log('success'); // ㈥
                }).catch(function (err) {});
                a = '55';
                console.log(a); // ㈧
                resolve(a);
            }, 200)
            console.log(2); // ㈢
        }).then(function (a) {
            console.log(a); // ㈦
        });
        console.log(3); // ㈨
    }
    demo();
    console.log(4); // ㈣
}());


发表评论