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异步调用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
