本文梳理了JavaScript中获取异步函数返回值的技术演进历程。从最初的同步阻塞误区,到回调函数、Promise、Generator组合方案,最终介绍ES7的Async/Await语法。通过对比各阶段代码示例,帮助开发者理解异步编程模式的演变及最佳实践。
JavaScript异步函数返回值获取方法
本文探讨一个常见技术问题:如何正确获取JavaScript异步函数的返回值?
错误尝试:同步思维处理异步
1. 错误尝试
在刚接触编程时,我最初的尝试方式如下:
<script>
function getSomething() {
var r = 0;
setTimeout(function() {
r = 2;
}, 10);
return r;
}
function compute() {
var x = getSomething();
alert(x * 2);
}
compute();
</script>
回调函数方案
2. 回调函数
实际弹出的结果并非预期的4,而是0。这揭示了异步操作的基本特性:
因此,需要采用回调技术来实现:
<script>
function getSomething(cb) {
var r = 0;
setTimeout(function() {
r = 2;
cb(r);
}, 10);
}
function compute(x) {
alert(x * 2);
}
getSomething(compute);
</script>
Promise方案
3. Promise
回调函数确实有效,我也曾长期沿用这种写法。遇到异步操作就传入回调函数。随后我了解到Promise是专门解决回调地狱问题的方案,于是开始使用Promise:
<script>
function getSomething() {
var r = 0;
return new Promise(function(resolve) {
setTimeout(function() {
r = 2;
resolve(r);
}, 10);
});
}
function compute(x) {
alert(x * 2);
}
getSomething().then(compute);
</script>
需要注意的是,Promise并未完全摒弃回调,只是回调的执行位置发生了改变。
Generator方案
4. Generator
之后我又学习了Generator,了解到它具有中断函数执行的能力,因此进行了新的尝试:
<script>
function getSomething() {
var r = 0;
setTimeout(function() {
r = 2;
it.next(r);
}, 10);
}
function *compute(it) {
var x = yield getSomething();
alert(x * 2);
}
var it = compute();
it.next();
</script>
这种写法实现了同步风格的代码逻辑来处理异步操作,看起来更加简洁。
Promise与Generator组合方案
5. Promise + Generator
后来听说Promise结合Generator才是处理异步的完美方式,于是尝试使用这种组合(尽管本例尚不足以完全体现二者结合的优势):
<script>
function getSomething() {
var r = 0;
return new Promise(function(resolve) {
setTimeout(function() {
r = 2;
resolve(r);
}, 10);
});
}
function *compute() {
var x = yield getSomething();
alert(x * 2);
}
var it = compute();
it.next().value.then(function(value) {
it.next(value);
});
</script>
Async/Await终极方案
6. Async
本以为至此已足够,但随后得知ES7提供了终极解决方案:async。
作为追求技术进步的开发者,自然不能落后:
<script>
function getSomething() {
var r = 0;
return new Promise(function(resolve) {
setTimeout(function() {
r = 2;
resolve(r);
}, 10);
});
}
async function compute() {
var x = await getSomething();
alert(x * 2);
}
compute();
</script>
至此,终于感到轻松。
后记:
上述所有示例在最新版本的Chrome浏览器中均可运行。这些简短的例子仅触及了相关名词的表面。
当然,这仅仅是“点”到为止。如果能激发读者深入学习相关知识的兴趣,便已达成目的。
以上就是本文分享的全部内容,希望有助于大家理解JavaScript异步函数的返回值获取方式。