最近做了一個智慧家居的APP,目前純JS程式碼已經4000多行,不包括任何引入的庫。還在不斷升級改造中。。。這個專案到處都是非同步。大多數都是3~4層呼叫。給我的感覺就是非同步當你習慣了,你會發現很爽。下面舉個最簡單的例子?
你知道怎麼返回一個非同步呼叫的值嗎?
也許你會這麼幹
function getValue(){ var a = 10; setTimeout( function(){ a += 10; }, 10 ); return a; }
你肯定得不到你想要的20
function test(){ var res = getValue(); return res; }
console.log( test() ); //結果10
為什麼?
因為settimeout的原因,把a += 10放在佇列中,等所有的同步程式碼完成之後,才輪到他執行。所以return的時候,這個a += 10 是沒有執行的,而且你也不知道,非同步到底什麼時候完成? 這個是不確定的,哪怕你設定了10ms,未必是10ms。。。。如果佇列前面有耗時較長的其他任務,10ms還是得不到響應。。。這樣的例子太多了。比如,我最近的專案,控制空調的關和開。。很顯然,這個時間受制於網路和晶片,以及空調的響應。。並不是設定了多長時間,就是那個時間返回。
那不知道他什麼時候,返回,怎麼拿到他的值?
用回撥!
function getValue2( fn ){ var a = 10; setTimeout( function(){ a += 10; fn && fn( a ); }, 10 ); return a; }
function test2(){ getValue2( function( res ){ console.log( res ); } ); }
test2();
你GET到了嗎?
下面就是一個簡單的非同步呼叫了:
var Q = { a : [], in : function( v ){ if( !/number|function/.test( typeof( v ) ) ) return; this.a.push( v ); return this; }, out : function(){ var me = this; var v = me.a.shift(); if( !v ) return; if( typeof( v ) == `function` ) { v(); me.out(); return; } setTimeout( function(){ me.out(); }, v ); } } function watch( res ){ var oDiv = document.createElement( "div" ); oDiv.innerHTML = res; // console.log( res ); document.body.appendChild( oDiv ); } Q.in( function(){ watch( "1 <strong style=`color:red`>延時3秒 -->輸出2</strong>" ); }) .in( 3000 ) .in( function(){ watch( "2 <strong style=`color:green`>延時2秒 -->輸出2</strong>" ); } ) .in( 2000 ) .in( function(){ watch( "3 <strong style=`color:blue`>後面沒有了</strong>" ); } ).out();