1

将来の「requestServer」でサーバーへのリクエストを開始します。特定の値 (リクエストが完了すると false から true に渡される) についてシステムをポーリングし、終了したら戻りたいと思います。

コードはそのようなものかもしれませんが、「while」は同期で「checkOperation」は非同期ですか?

return requestServer().then((operation) {
  var done = false;
  while (done)
    return checkOperation(operation).then((result) {
      done = (result == true);
    });
    sleep(10);
  }
});

何か案は ?

4

4 に答える 4

2

これはまさにあなたが望むものではないと思いますが、私が知る限り、実行をブロックする方法はないため、コールバックを使用する必要があります。

void main(List<String> args) {

  // polling
  new Timer.periodic(new Duration(microseconds: 100), (t) {
    if(isDone) {
      t.cancel();
      someCallback();
    }
  });

  // set isDone to true sometimes in the future
  new Future.delayed(new Duration(seconds: 10), () => isDone = true);
}

bool isDone = false;

void someCallback() {
  print('isDone: $isDone');
  // continue processing
}

もちろん、関数は Dart のファースト クラス メンバーであるため、コールバックをハードコードする代わりにパラメーターとして渡すことができます。

于 2014-03-11T18:07:33.783 に答える
1

非同期の場合、ポーリングはうまく機能しません。完了しなければならないものからのシグナルを待つ方がよいでしょう。

Günter Zöchbauer's answer は、タイマーでサンプリングすることにより、とにかくポーリングする方法を示しています。

別の方法として、ブール値を実行せずに、準備ができたら別の未来を完成させる方がよいでしょう。これはビジー ポーリングであり、結果が返されるとすぐに再度ポーリングするため、必要以上に集中する可能性があります。できるだけ早く結果を必要としない場合は、タイマー ベースのポーリングを使用する方が効率的です。

return requestServer().then((operation) {
  var completer = new Completer();
  void poll(result) {     
    if (!result) { 
      operation.then(poll, onError: completer.completeError);
    } else {
      completer.complete();
    }
  }
  poll(false);
  return completer.future;
});

(requestServer がないため、コードは実際にはテストされていません)。

于 2014-03-12T07:20:28.897 に答える
1

Future を返すビルド関数が必要な場合は、Completers を使用すると便利な場合があります。requestServer() も未来に生きていると考えてください。そのため、未来として結果を脅かすことになります。

    return requestServer().then((operation) {

      // This is necessary then you want to control async 
      // funcions.
      Completer completer = new Completer();

      //
      new Timer.periodic(const Duration(seconds: 10), (_) {
        checkOperation(operation).then((result) {

          // Only when the result is true, you pass the signal
          // that the operation has finished.
          // You can alse use `completer.complete(result)` if you want
          // to pass data inside of the future.
          if (result == true) completer.complete();
        });
      });

      // You return the future straight away.
      // It will be returned by requestServer();
      return completer.future;
    });
于 2014-03-13T01:51:57.460 に答える