JavaScript 异步调用
问题
可修改下面的aa()函数,目的是在一抄后用console.log()输出want-value
functionaa(){ setTimeout(function(){ return"want-value"; },1000); }
但是,有额外要求:
aa()函数可以随意修改,但是不能有console.log()
执行console.log()语句里不能有setTimeout包裹
解答
也许这是个面试题,管它呢。问题的主要目的是考察对异步调用执行结果的处理,既然是异步调用,那么不可能同步等待异步结果,结果一定是异步的
setTimeout()经常用来模拟异步操作。最早,异步是通过回调来通知(调用)处理程序处理结果的
functionaa(callback){ setTimeout(function(){ if(typeofcallback==="function"){ callback("want-value"); } },1000); } aa(function(v){ console.log(v); });
不过回调在用于稍大型一点的异步应用时,容易出现多层嵌套,所以之后提出了一些对其进行“扁平”化,这一部分可以参考闲谈异步调用“扁平”化。当然Promise是非常流行的一种方法,并最终被ES6采纳。用Promise实现如下:
functionaa(){ returnnewPromise(resolve=>{ setTimeout(function(){ resolve("want-value"); },1000); }); } aa().then(v=>console.log(v));
就这个例子来说,它和前面回调的例子大同小异。不过它会引出目前更推荐的一种方法——async/await,从ES2017开始支持:
functionaa(){ returnnewPromise(resolve=>{ setTimeout(function(){ resolve("want-value"); },1000); }); } asyncfunctionmain(){ constv=awaitaa(); console.log(v); } main();
aa()的定义与Promise方法中的定义是一样的,但是在调用的时候,使用了await,异步等待,等待到异步的结果之后,再使用console.log()对其进行处理。
这里需要注意的是await只能在async方法中使用,所以为了使用await必须定义一个async的main方法,并在全局作用域中调用。由于main方法是异步的(申明为async),所以如果main()调用之后还有其它语句,比如console.log("hello"),那么这一句话会先执行。
async/await语法让异步调用写起来像写同步代码,在编写代码的时候,可以避免逻辑跳跃,写起来会更轻松。(参考:从地狱到天堂,Node回调向async/await转变)
当然,定义main()再调用main()这部分可以用IIFE封装一下,
(async()=>{ constv=awaitaa(); console.log(v); })();
总结
以上所述是小编给大家介绍的JavaScript异步调用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!