今天研究一個小問題: 怎麼拿到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>
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仍然沒有放棄回調,只是回調的位置發生了改變。
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>
同步的寫法,能實現非同步的邏輯,感覺高大上了很多。
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>
#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非同步函數傳回值的取得方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!