4

このオンラインのチュートリアルのいくつかを理解するのに少し問題があるので、なぜここで質問しているのですか。(ActionScript 3、Adobe AIR、およびFlash Professional CS5.5を使用)

AS3ドキュメントクラスに非常に重い関数があり、非同期で実行する必要があるため、MovieClip自体のコードは停止しません(理由は聞かないでください。そのようにする必要があります)。

つまり、簡単に言えば、このドキュメントクラス関数(StartNow)を非同期で実行するにはどうすればよいですか?コードはドキュメントクラスまたはムービークリップに配置できます。どこに配置してもかまいません。それは比較的単純で一般的な慣習のようですが、私の研究はすべて何も掘り下げていません。

ありがとう!

4

2 に答える 2

4

ターゲットが Flash Player 11.4 の場合、このような重い機能を割り当てることができる Worker オブジェクトがあります。私は FP11 を持っていませんでしたが、最終的に、反復ごとに合計で 300 秒以上持続する手続き型ジェネレーターを作成しました。エンター フレーム リスナーと組み合わせて、状態ベースのアプローチを使用する必要がありました。私の場合、複雑な生成プロセス全体が、妥当な期間内に完了するのに十分小さい論理チャンクに分割され、現在の生成フェーズを追跡する変数がありました。そのため、別のフレームが生成関数を呼び出すと、その変数から最後に完了したステップを読み取り、そのデータ セットを使用して 1 つの追加ステップを実行し、新しい値を保存してフレームを終了しました。これはそのままでは純粋な非同期プロセスではなく、疑似マルチタスキング アプローチです。これは、SWF の遅延を引き起こす関数が分割可能である場合に適しています。

于 2012-11-22T07:30:50.510 に答える
2

Flash では、関数を非同期で実行するようなことはありません。Workers を使用したい場合を除き (Vesper が言ったように)、自分で実行する必要があります。ワーカーは別のプロセスを提供します。それ以外の場合は、計算を部分に分割する必要があります。これはあなたがそれを行う方法です:

イメージング「トレース」は非常に負荷の高い操作です。そうではありませんが、説明するだけです。この単純な for ループはフレームで実行され、フレームが実際にレンダリングされる前にすべて計算されるため、フレームレートが低下します。

for(var i:int = 0; i < 1000; i ++)
{
   trace(i); // heavy calculation here
}

したがって、計算を部分に分割し、時間をかけて計算を実行できるように分割する必要があります。

そのためには、毎回ループの一部を取る関数を作成する必要があります。

calculatePart(0, 1000, 20);

function calculatePart(startIndex:int, endIndex:int, amountPerRun:int)
{
    for(var i:int = startIndex; (i < startIndex + amountPerRun) || (i < endIndex); i ++)
    {
        trace(i); // heavy calculation here
    }
    if (i < endIndex)
    {
        calculatePart(i, endIndex, amountPerRun);
    }
}

これは実際には、最初のコードの単純な for ループと同じ関数であり、1000 トレースも出力します。部分的に実行する準備ができていますが、これはまだ非同期ではありません。関数を簡単に変更できるようになったため、関数は時間の経過とともに動作します。これには を使用しsetTimeoutます。ENTER_FRAMEこれには、イベント リスナーまたはクラスを使用することもできますがTimer、この例のために、明確にしておくようにしています。

calculatePart(0, 1000, 20, 100);

function calculatePart(startIndex:int, endIndex:int, amountPerRun:int, timeBeforeNextRun:Number)
{
    for(var i:int = startIndex; (i < startIndex + amountPerRun) && (i < endIndex); i ++)
    {
        trace(i); // heavy calculation here
    }
    if (i < endIndex)
    {
        setTimeout(calculatePart, timeBeforeNextRun, i, endIndex, amountPerRun, timeBeforeNextRun);
    }
}

ご覧のとおり、timeBeforeNextRunパラメーターを追加しました。この例を実行すると、20 トレースが出力されるまでに 100 ミリ秒かかることがわかります。

非常に低く設定すると、計算は非常に高速に実行されようとしますが、もちろん、より短い時間でより多くのことを実行しようとするだけでは、余分な速度を得ることはできません. 時間変数と量変数をいじる必要があり、どちらが実際にパフォーマンスが向上するか (またはラグが少ないか) をテストできます。

 // more time between a run, less calculations per run
 calculatePart(0, 1000, 30, 10);

 // more calculations per run, more time between a run
 calculatePart(0, 1000, 100, 30);

お役に立てれば。

時間のよりスマートな計算を使用したい場合は、このユーティリティ クラスが非常に役立つことがわかりました。これは、計算に実際にかかった時間を測定し、時間自体を変更します。

于 2012-11-22T09:47:47.237 に答える