2014-04-30 2 views
3

순차적으로 확인해야하는 URL 목록이 있습니다. URL에서 검색된 콘텐츠 중 하나가 주어진 기준과 일치하면 다음 URL을 테스트해야합니다. 그렇지 않으면 중지해야합니다.비동기 작업을 연결하는 방법은 무엇입니까?

문제는 주어진 URL에 대한 콘텐츠를 가져 오는 것이 비동기 작업이므로 간단한 for-each 루프를 사용할 수 없다는 것입니다.

가장 좋은 방법은 무엇입니까? 대한

지금 내 코드는 다음과 같습니다 내가 가진

List<String> urls = [/*...*/]; 
void f() { 
    if (urls.isEmpty) return; // no more url available 
    final url = urls.removeAt(0); 
    getContent(url).then((content) { 
    if (!matchCriteria(content)) f(); // try with next url 
    else doSomethingIfMatch(); 
    }); 
} 
f(); 

답변

1

Quiver package 비동기로 반복하는 여러 기능이 포함되어 있습니다.

doWhileAsync, reduceAsyncforEachAsync이 계산은 다음의 요소를 처리하기 전에 완료하기를 기다리고, 반복 가능 객체에의 원소에 비동기식 계산을 수행한다.

doWhileAsync

은 원 정확히 것 같다 :

List<String> urls = [/*...*/]; 
doWhileAsync(urls, (url) => getContent(url).then((content) { 
    if (!matchCriteria(content)) { 
    return new Future.value(true); // try with next url 
    } else { 
    doSomethingIfMatch(); 
    return new Future.value(false); 
    } 
})); 
0

하나의 아이디어가있는에 반응 할 또 다른 Future에 전체 작업의 결과를 분리해서하는 것입니다. 이 미래는 발견 된 URL의 내용 또는 유효하거나 오류가 반응 할 수있는 내용을 전송합니다. 비동기식 getContent 작업이 완료되면 미래의 결과 또는 오류가 발생하거나 다시 시도됩니다. 작업을 실행하는 동안 urls 목록을 다른 방법으로 수정하면 안된다는 (그리고 사용자의) 접근 방식에서는 그러지 마십시오. 목록이 각 시퀀스의 시작에서 새로 작성되면 (예와 같이) 모든 것이 정상입니다.

List<String> urls = [/*...*/]; 
Completer<String> completer = new Completer<String>(); 

void f() { 
    if (urls.isEmpty) completer.completeError(new Exception("not found")); 
    final url = urls.removeAt(0); 
    getContent(url).then((content) { 
    if (!matchCriteria(content)) f(); // try with next url 
    else completer.complete(content); 
    }).catchError((error) { completer.completeError(error); }); 
} 

completer.future.then((content) { 
    // url was found and content retrieved  
}).catchError((error) { 
    // an error occured or no url satisfied the criteria 
}); 
관련 문제