前言
我们知道javascript是没办法阻塞的,所有的等待只能通过回调来完成,这就造成了回调嵌套的问题,导致代码乱到爆,这时候Await就有用处了。
对于await的底层机制这里就不详述了,以免将文章的篇幅拖的很长,需要的朋友们可以参考这篇文章://www.jb51.net/article/123257.htm,下面开始本文的正式内容。
利用Await减少回调嵌套
我们大家在开发的时候,有时候需要发很多请求,然后经常会面临嵌套回调的问题,即在一个回调里面又嵌了一个回调,导致代码层层缩进得很厉害。
如下代码所示:
ajax({ url: "/list", type: "GET", success: function(data) { appendToDOM(data); ajax({ url: "/update", type: "POST", success: function(data) { util.toast("Success!"); }) }); } });
这样的代码看起来有点吃力,这种异步回调通常可以用Promise优化一下,可以把上面代码改成:
new Promise(resolve => { ajax({ url: "/list", type: "GET", success: data => resolve(data); }) }).then(data => { appendToDOM(data); ajax({ url: "/update", type: "POST", success: function(data) { util.toast("Successfully!"); }) }); });
Promise提供了一个resolve,方便通知什么时候异步结束了,不过本质还是一样的,还是使用回调,只是这个回调放在了then里面。
当需要获取多次异步数据的时候,可以使用Promise.all解决:
let orderPromise = new Promise(resolve => { ajax("/order", "GET", data => resolve(data)); }); let userPromise = new Promise(resolve => { ajax("/user", "GET", data => resolve(data)); }); Promise.all([orderPromise, userPromise]).then(values => { let order = values[0], user = values[1]; });
但是这里也是使用了回调,有没有比较优雅的解决方式呢?
ES7的await/async可以让异步回调的写法跟写同步代码一样。第一个嵌套回调的例子可以用await改成下面的代码:
// 使用await获取异步数据 let leadList = await new Promise(resolve => { ajax({ url: "/list", type: "GET", success: data => resolve(data); }); }); // await让代码很自然地像瀑布流一样写下来 appendToDom(leadList); ajax({ url: "/update", type: "POST", success: () => util.toast("Successfully"); });
Await让代码可以像瀑布流一样很自然地写下来。
第二个例子:获取多次异步数据,可以改成这样:
let order = await new Promise( resolve => ajax("/order", data => resovle(data))), user = await new Promise( resolve => ajax("/user", data => resolve(data))); // do sth. with order/user
内容版权声明:除非注明,否则皆为本站原创文章。