2012-10-27 46 views
7

我有以下示例代碼 - 第一部分可以導致異步調用或不 - 它應該繼續。我不能將其餘的代碼放在異步回調中,因爲當條件爲假時它需要運行。那麼如何做到這一點?有條件地調用異步函數在節點

if(condition) { 
    someAsyncRequest(function(error, result)) { 
     //do something then continue 
    } 
} 

//do this next whether condition is true or not 

我認爲把代碼來後,一個功能可能是去調用異步調用以上或在其他人通話,如果條件爲假內的函數的方式 - 但有一個替代方法那不需要我在功能上分解它?

+0

異步等待包可以幫助(允許以同步樣式編寫異步代碼,支持異常等)https://www.npmjs.com/package/asyncawait - 在將來的Node版本中也會本地支持此類語法,請參閱https:// github。com/nodejs/promises/issues/4 –

回答

3

只是聲明只要你需要它來運行一些其他的功能:

var otherFunc = function() { 
    //do this next whether condition is true or not 
} 

if(condition) { 
    someAsyncRequest(function(error, result)) { 
     //do something then continue 

     otherFunc(); 
    } 
} else { 
    otherFunc(); 
} 
+3

是的這就是我現在所提到的 - 只是想知道是否有一種方法避免封裝函數中的代碼 – cyberwombat

+0

@Yashua,不,因爲您的someAsyncRequest是異步的,所以不能保證當它被執行時,由於JavaScript本身並不是*多線程的,所以你不能只是暫停程序的某些部分,直到進行一些異步調用。因此,您需要保護代碼的一部分,以便稍後在函數內部執行,並在適當的時間(即,立即或僅在執行異步代碼時)調用它。 –

3

只是一個另一種方式來做到這一點,這是我的抽象圖案。可能有一些圖書館(承諾?)處理同樣的事情。

function conditional(condition, conditional_fun, callback) { 
    if(condition) 
     return conditional_fun(callback); 
    return callback(); 
} 

,然後在代碼,你可以寫

conditional(something === undefined, 
      function(callback) { 
       fetch_that_something_async(function() { 
        callback(); 
       }); 
      }, 
      function() { 

         /// ... This is where your code would continue 


      }); 
0

我會建議使用clojurescript它有一個真棒core-async庫異步調用處理時使生活超級簡單。

在你的情況,你會寫是這樣的:

(go 
    (when condition 
    (<! (someAsyncRequest))) 
    (otherCodeToHappenWhetherConditionIsTrueOrNot)) 

注意go宏,這將導致身體異步運行,並<!功能,這將阻止,直到異步函數將返回。由於<!函數在when條件中,因此只有在條件爲真時纔會阻止。

+0

@kleopatra請查看我對編輯的回答。我希望現在好一點。 – Asher

+0

感謝您的更新:-) – kleopatra

7

我在Node中經常使用的庫是Async(https://github.com/caolan/async)。最後,我檢查了這也支持瀏覽器,所以你應該能夠在你的發行版中使用npm/concat/minify。如果您在服務器端使用此功能,則只應考慮https://github.com/continuationlabs/insync,這是一個稍微改進的Async版本,其中部分瀏覽器支持已刪除。

我在使用條件異步調用時使用的常見模式之一是使用我要按順序使用的函數並將其傳遞給async.waterfall。

我已經在下面包含了一個例子。

var tasks = []; 

if (conditionOne) { 
    tasks.push(functionOne); 
} 

if (conditionTwo) { 
    tasks.push(functionTwo); 
} 

if (conditionThree) { 
    tasks.push(functionThree); 
} 

async.waterfall(tasks, function (err, result) { 
    // do something with the result. 
    // if any functions in the task throws an error, this function is 
    // immediately called with err == <that error> 
}); 

var functionOne = function(callback) { 
    // do something 
    // callback(null, some_result); 
}; 

var functionTwo = function(previousResult, callback) { 
    // do something with previous result if needed 
    // callback(null, previousResult, some_result); 
}; 

var functionThree = function(previousResult, callback) { 
    // do something with previous result if needed 
    // callback(null, some_result); 
}; 

當然你可以使用promise來代替。在任何情況下,我都喜歡通過使用異步或promise來避免嵌套回調。

你們當中有些人可以通過不使用嵌套回調避免的事情是可變的碰撞,吊裝錯誤,「行軍」向右>>>>,難讀碼等

+1

FWIW,Async是這裏涵蓋的第一種反模式的替代方案: http://webapplog.com/seven-things-you-should-stop-doing-with-node-js / – zedd45