2013-05-25 2 views
1

Futures를 처리하는 방식을 바꿀 수 있는지 궁금해하는 Futures의 다음 예제 (아래의 예 1)가 발생하여 순서를 유지하는 중첩 된 함수 호출을 모두 제거했습니다. 처리, 그러나 나는 약간 지저분한 찾을 들여 쓰기가 발생합니다.Async Futures completed to completion

그러나 변경된 버전의 프로그램은 작동하지 않았습니다. 처리 순서를 유지하지 않고 기능이 완료 될 때까지 "대기"하지 않았습니다. 예를 들어 첫 번째 호출 (fGetUserInput)에서 돌아 오기 전에 다른 후속 함수가 호출되었습니다.

예 1에서 모든 "1 단계" "새로운 미래"가 순차적으로 처리되는 이유는 무엇입니까? 예제 2에서 변경된 코드는 처리 순서가 유지되지 않습니다. fGetUserInput에 대한 호출이 처리되는 동안 그 다음에 나오는 선물 중 하나가 처리됩니까?

모든 문장이 동기식이기 때문에 "예제 1"이 "작동"합니까?

"runAsync"에 대한 참조가 나타났습니다. 그게 내가 원하는 것을 성취하는데 사용될 수 있습니까? (모든 들여 쓰기가없는 순서대로 처리). 다음과 같은 콘솔 출력 순서에

// Example 1. Code that I encountered for Futures // 

import 'dart:async'; 

main() { 

    new Future(() => print('1')) 
    .then((_) => print('a')) 
    .then((_) => print('b')); 

    new Future(() => print('2')) 
    .then((_) => print('c')) 
    .then((_) => print('d')); 

    new Future(() => print('3')) 
    .then((_) => 
     new Future(() => print('e')) 
     .then((_) => print('f')) 
    ); 

    new Future(() => print('4')) 
    .then((_) => 
     new Future(() => print('g')) 
     .then((_) => print('d')) 
    ); 
} 

이상의 결과 : - 나는 이해했다 생각했다

 
1 a b 2 c d 3 4 e f g d 

.

// Example 2. Altered version of my code which // 
    // does not preserve the order of processing, // 
    // which is necessary for program to function. // 

    new async.Future(() => fGetUserInput()) 
    .then((lInput) { 
    iMaxIters = int.parse(lInput[4]); 
    tClearTable = (lInput[5] == "y"); 

    iDivisor = fInitialize(iMaxIters); 

    tgPrint = false; // printing off 

    sUri = 
    "postgres://${lInput[1]}:${lInput[2]}@localhost:5432/${lInput[3]}"; 
    sStartTime = lInput[7]; 
    }) 
    .catchError((oError) => fFatal("Get User Input", oError)); 

    new async.Future(() => fConnectToDb(sUri, sStartTime)) 
    .then((bool tConnected) { 
    if (ogDb == null) 
     fFatal("Unable to connect to database", ""); 
    print ("Processing database ......"); 
    }) 
    .catchError((oError) => fFatal("Connect to Db", oError)); 

    new async.Future(() => fClearTable(tClearTable)) 
    .then((sResult) => print (sResult+"\n")) 
    .catchError((oError) => fFatal("Clear Table", oError)); 

    new async.Future(() => fProcessInserts(iMaxIters, iDivisor)) 
    .then((sResult) => print ("")) 
    .catchError((oError) => fFatal("Process Inserts", oError)); 

    new async.Future(() => fSetupRandKeys()) 
    .then((sResult) => print ("")) 
    .catchError((oError) => fFatal("Setup Random Keys", oError)); 

    new async.Future(() => fProcessUpdates(iMaxIters, iDivisor)) 
    .then((sResult) { 
    String sTotValue = fFormatAmount(igGrandTotAmt, true, 2); 
    fPrint ("Grand Total added to database = \$${sTotValue}"); 
    ogDb.close(); 
    exit(0); 
    }) 
    .catchError((oError) => fFatal("Process Updates", oError)); 
} 

void fFatal (String sMessage, Error oError) { 
    print("\n\nFatal Error. $sMessage\n${oError}"); 
    exit(1); 
} 

async.Future<String> fProcessInserts(int iMaxIters, int iDiv) { 
    async.Completer oCompleter = new async.Completer<String>(); 

    int iTot = 0; 
    Function fLoop; 

    print ("\nProcessing Inserts ......"); 
    fResetAndStartWatch(); 

다음은 위의 변경에 내 코드는 이전이며, 다음과 같은 예 3 확인 작업 표시 -이 :

따라서, 다음과 같이 나는 그것을 테스트하려면 코드를 수정했습니다. 나는 들여 쓰기의 범위를 좋아하지 않으며 함수 호출이 많은 상황에서는 들여 쓰기의 정도가 증가합니다. 나는 그것을하는 더 우아한 방법을 희망하고 있었다.

// Example 3: The original version of my code // 
    // which does preserve the order of processing // 
void main() { 

    print(""); 

    String sCheckPoint = "Get User Input"; 
    fGetUserInput() 
    .then((lInput) { 
    int iMaxIters = int.parse(lInput[4]); 
    bool tClearTable = (lInput[5] == "y"); 

    int iDiv = fInitialize(iMaxIters); 

    tgPrint = false; // printing off 

    String sUri = 
     "postgres://${lInput[1]}:${lInput[2]}@localhost:5432/${lInput[3]}"; 

    sCheckPoint = "Connect to Database"; 
    fConnectToDb(sUri, lInput[7]).then((bool tConnected) { 
     if (ogDb == null) 
     fFatal(sCheckPoint, "Unable to conenct to Db"); 
     print ("Processing database ......"); 
     sCheckPoint = "Clear Table"; 
     fClearTable(tClearTable).then((sResult) { 
     print (sResult+"\n"); 
     sCheckPoint = "Process Inserts"; 
     fProcessInserts(iMaxIters, iDiv).then((sResult) { 
      print; 
      sCheckPoint = "Set-up Random Keys"; 
      fSetupRandKeys().then((sResult) { 
      print; 
      sCheckPoint = "Process Updates"; 
      fProcessUpdates(iMaxIters, iDiv).then((sResult) { 
       String sTotValue = fFormatAmount(igGrandTotAmt, true, 2); 
       fPrint ("Grand Total added to database = \$${sTotValue}"); 
       ogDb.close(); 
       exit(0); 
      }); 
      }); 
     }); 
     }); 
    }); 
    }) 
    .catchError((oError) => fFatal(sCheckPoint, oError)); 
} 

void fFatal (String sMessage, Error oError) { 
    print("\n\nFatal Error. $sMessage\n${oError}"); 
    exit(1); 
} 

async.Future<String> fProcessInserts(int iMaxIters, int iDiv) { 
    async.Completer oCompleter = new async.Completer<String>(); 

    int iTot = 0; 
    Function fLoop; 

    print ("Processing Inserts ......"); 
    fResetAndStartWatch(); 

답변

1

들여다보기가 가능하여 들여 쓰기가 상당히 줄어들 수 있습니다.

단점은 중첩 된 범위를 얻지 못하는 것입니다. 단점은 비동기 블록 사이에 전파 할 값이 두 개 이상 있지만 몇 가지 방법으로 해결할 수있는 경우 유용 할 수 있습니다.

// Example 3 with chaining 
void main() { 
    String checkPoint = "Get User Input"; 
    getUserInput().then((input) { 
    int maxIters = int.parse(input[4]); 
    bool clearTable = (input[5] == "y"); 

    int div = initialize(maxIters); 

    shouldPrint = false; // printing off 

    String uri = 
     "postgres://${input[1]}:${input[2]}@localhost:5432/${input[3]}"; 

    checkPoint = "Connect to Database"; 
    return connectToDb(uri, input[7]).then((bool connected) { 
     if (db == null) 
      fatal(checkPoint, "Unable to conenct to Db"); 
     print ("Processing database ......"); 
     checkPoint = "Clear Table"; 
     return clearTable(shouldClearTable); 
    }).then((result) { 
     print (result+"\n"); 
     checkPoint = "Process Inserts"; 
     return processInserts(maxIters, div); 
    }).then((result) { 
     print(''); 
     checkPoint = "Set-up Random Keys"; 
     return setupRandKeys(); 
    }).then((result) { 
     print(''); 
     checkPoint = "Process Updates"; 
     return processUpdates(maxIters, div); 
    }).then((result) { 
     String totValue = formatAmount(grandTotAmt, true, 2); 
     print("Grand Total added to database = \$${totValue}"); 
     return db.close(); 
     // exit(0); pretty much never call exit() 
    }); 
    }).catchError((error) => fatal(checkPoint, error)); 
} 

편집 :

여기에 체인을 함께 예 3의 아차, 더 밀접하게 나는 범위 지정 문제의 비트를 가지고보고 ... 나는 범위에 필요한 바르를 캡처 단지 중첩의 수준을 추가 다음 블록을 통해 액세스 할 수 있습니다. 나는 또한 다트에서 그렇게하지 않기 때문에 헝가리 인 표기법을 제거합니다 :)

+0

고마워, 나는 그것을 시도 할 것이다. 그러나 표기법에 대해 확실하지 않습니다. 다시보고 할게. –