for迴圈非同步呼叫介面,怎樣判斷資料已經返回完成?
阿新 • • 發佈:2019-01-26
在工作中遇到了一個for迴圈呼叫介面的例子:首先要根據一個叢集ID,去呼叫介面查詢此叢集下的所有“名稱空間”,接著再用for迴圈來一個個查詢所有“名稱空間”下的“例項”,eg:
<script type="text/javascript"> namespaceService.getNamespaceList(clusterId,...(其它引數)).then( function( response ){ var namespaceList = response.items; var sensitiveWordFlag = false; for( var i = 0; i < namespaceList.length; i++){ clusterService.getPods( namespaceList[i].name, ...(其它引數)).then( function( res ){ for( var j = 0;j<res.length;j++ ){ if( res[j].name.test("abc") == true){ window.alert("含有敏感字元abc"); sensitiveWordFlag = true; return; } } } ) if( !sensitiveWordFlag ){ window.alert("所有返回資料內容沒有敏感字元"); } } } ); </script>
大家應該看出問題了,最後那個函式裡面最後一個 if 的寫法是有問題的,因為介面的呼叫是非同步執行的,一個名稱空間的資料還沒有返回,它就先直接走進去了。那我們該如何改寫呢?也就是要加一個怎樣的判斷條件,才能控制它是在所有的介面資料都在執行完上一個 if 以後,再走這一個 if ?我們只需再加一個 變數即可:
<script type="text/javascript"> namespaceService.getNamespaceList(clusterId,...(其它引數)).then( function( response ){ var namespaceList = response.items; var sensitiveWordFlag = false; // 敏感字元標識 var count = 0; // 執行次數, 用於判斷是否遍歷完所有namespace for( var i = 0; i < namespaceList.length; i++) { // 如果之前有敏感字元,就不再遍歷 if (sensitiveWordFlag) { break; } clusterService.getPods( namespaceList[i].name, ...(其它引數)).then( function( res ){ // 遍歷一個namespace ,count + 1 count++; // 如果之前有敏感字元,就不再遍歷 if (sensitiveWordFlag) { return; } // 判斷所有例項是否有敏感字元 for( var j = 0;j<res.length;j++ ){ if( res[j].name.test("abc") == true){ sensitiveWordFlag = true; window.alert("含有敏感字元abc"); return; // break; } } // 當標識位是False,且計數等於namespace長度的時候,說明已經遍歷所有的namespace,也沒發現敏感字元 if( !sensitiveWordFlag && count == namespaceList.length ){ window.alert("所有返回資料內容沒有敏感字元"); } } ); // getPods } } ); </script>
再來看一種實現,如果需要提示使用者和哪些例項衝突了,那麼你就需要將衝突的例項儲存到一個臨時變數裡。但你會發現需要窮盡所有的例項,才能確定衝突的例項。(效能問題,可想而知)
<script type="text/javascript"> namespaceService.getNamespaceList(clusterId,...(其它引數)).then( function( response ){ var namespaceList = response.items; var sensitiveWord = []; //用於記錄敏感的例項名稱 var count = 0; // 執行次數, 用於判斷是否遍歷完所有namespace for( var i = 0; i < namespaceList.length; i++) { clusterService.getPods( namespaceList[i].name, ...(其它引數)).then( function( res ){ // 遍歷一個namespace ,count + 1 count++; // 判斷所有例項是否有敏感字元 for( var j = 0;j<res.length;j++ ){ if( res[j].name.test("abc") == true){ // 儲存敏感的例項名稱 sensitiveWord[sensitiveWord.length] = res[j].name; } } // 當遍歷完所有namespace時,判斷sensitiveWord if( count == namespaceList.length ){ if (sensitiveWord.length > 0){ window.alert("含有敏感字元abc"); // sensitiveWord儲存的值,是所有敏感例項的名稱 } else { window.alert("所有返回資料內容沒有敏感字元"); } } } ); // getPods } } ); </script>