-1

アロハ。これは、何十年にもわたって潜んでいた後の私の最初の質問です。この質問の冗長で直接的な形式、および受け入れ可能な回答の制限についてお詫び申し上げますが、私は貢献するためにここにいます。他の質問(たとえば、Node.jsでの非同期関数の長いネストJavascriptでの連鎖コールバックの可読性を回避する方法)では、満足のいく答えが得られないという問題があります。

いくつかのJavascriptコールバックを実行して、4つのアクションのシーケンスが次々に発生するようにします。ソースは次のとおりです。

var self = this;
fade(div, fadeIn, -20, function() {
  load(unload, dataOut, -10, function() {
    load(self, dataIn, 10, function() {
      fade(div, fadeOut, 20),0);
      unload = self;}
    );}
  );}
);

load()関数とfade()関数は、内部のセマンティックの詳細を除いて非常に似ており、次のようになります。

function load(menuCategory, data, step, callback) {
  menuCategory.parentNode.style.width = data+"px";
  data += step;
  if(dataIn <= data && data <= dataOut) {
    setTimeout(function() { load(menuCategory,data,step,callback) }, 15);
  } else if(callback && (typeof(callback) == 'function')) { 
    callback();}
}

この混乱に関連するいくつかの質問がありますが、最初に私が探していない答えをあなたに与えましょう。jQueryを使用した回答は受け入れられません。他のタイミングまたは「シンクロニシティ」フレームワークまたはモジュールを使用した回答は受け入れられません。実行をブロックする理由を質問する回答は受け入れられません。Javascript以外の言語を使用した回答は受け入れられません。抽象的でない回答も受け入れられますが、最終的な解決策は可能な限り抽象的である必要があります。つまり、回答は、類似しているがわずかに異なるさまざまなアクションに対応できる必要があります。

これが私の主な質問です:ここで起こっているコールバック地獄を減らすために、これらのアクションを順番に適用するために使用できる関数/オブジェクトはありますか?言い換えると、オブジェクト/関数が個別に繰り返される(つまり渡される)ときに、オブジェクト/関数が各アクションを同期的に実行できた場合、オブジェクトはどのようになりますか?

二次的な質問:このコールバックビジネスが他の言語でgoto()にどれほど似ているか知っている人はいますか?つまり、このコールバックのネストは、私にとって非常に厄介でエレガントではないと感じます。このクレイジーなビジネスを減らすために開発中またはすでに開発中のJavascript言語構造はありますか?コールバックのネストは、従うのが最も難しいロジックフローの一部です。ぎこちなく感じます。

ここでの私の目標は、タイトでエレガント、魅力的な、自家製のJavascriptオブジェクト/関数(for()ループまたは同等のものを呼び出すことができます)で、これらの操作を各アクションに順番に適用することです。これまでお読みいただき、誠にありがとうございました。:)

4

3 に答える 3

6

setTimeout(func(),0)同期して実行するために使用する

いいえfunc()。同期実行に使用するかsetTimeout(func, 0)、実行をキューに入れます(これにより非同期になります)。

setTimeout(func[…],0)このアクションをレンダリングされたWebページオブジェクトの実行キューに配置する「最も洗練された」方法ですか?言い換えれば、実行をブロックする(つまり、これらのことを順番に実行する)「よりエレガントな」方法はありますか?

はい、これが標準的な方法です。ただし、これは実行をブロックせ、シーケンスとは関係ありません。実行が同期している場合は実行するだけです。そうでない場合は、コールバックを処理する必要があり、新しいタスクをキューに入れることは役に立ちませ

このコールバックビジネスが他の言語でgoto()にどれほど似ているか知っている人はいますか?つまり、このコールバックのネストは、私にとって非常に厄介でエレガントではないと感じます。このクレイジーなビジネスを減らすために開発中またはすでに開発中のJavascript言語構造はありますか?

いいえ、私は他の言語を認識していませんが、afaikgotoは非同期アクションを処理しないため、同期の制御フロー構造化ステートメントです。

しかし、いいえ、コールバック地獄で継続渡しスタイルを回避するのに役立つJavaScript言語構造(「シンタックスシュガー」)はありません。

ここで起こっているコールバック地獄を減らすために、これらのアクションを順番に適用するために使用できる関数/オブジェクトはありますか?言い換えると、オブジェクト/関数が個別に繰り返される(つまり渡される)ときに、オブジェクト/関数が各アクションを同期的に実行できた場合、オブジェクトはどのようになりますか?

ここでの私の目標は、タイトでエレガント、魅力的な、自家製のJavascriptオブジェクト/関数(for()ループまたは同等のものを呼び出すことができます)で、これらの操作を各アクションに順番に適用することです。

ここでも、「同期」ではなく「順次」が必要です:-)はい、コールバックの処理を容易にする[ハンドコーディング/自家製]ソリューションがあります。あなたが言及したこれらのコールバック組織ライブラリはあなたを満足させないので、私は非常にエレガントで魅力的なPromiseApiとそのDeferredオブジェクトを調べることをお勧めします(概念の未来と約束を参照してください)。

于 2012-09-26T01:21:56.453 に答える
2

ここでsetTimeoutを使用している理由がわかりません。コールバックをキューに入れる必要はありません。次の構造は、fade()とload()がコールバックの実行を正しく処理することを前提として機能します。

fade(div, fadeIn, -20, function() {
    load(unload, dataOut, -10, function() {
        load(self, dataIn, 10, function() {
            fade(div, fadeOut, 20),0);
        });
    )};
)};

検討する必要のあるもう1つのトピックは、先物および先物とも呼ばれる約束です。その本質的には、ネストされたコールバックを具体的に処理するコーディングパターンです。ルートで、すぐに返されるPromiseオブジェクトを作成し、メソッドの実行が完了すると、promiseでメソッドを起動して、次の関数を実行できるようにします。javascriptの書き方は異なりますが、理解しやすく、非常に便利です。

于 2012-09-26T01:15:29.987 に答える
1

結局のところ、私の質問に対する「最良の」答えとしてふさわしい実践はイベントです。特に、私が言及しているプラ​​クティスは、Node.jsのEventEmitter、またはクライアントブラウザーでのカスタムイベントとイベントリスナーの作成によって最もよく説明されています。Promise APIとそのディファレンスモデルは興味深いものですが、コアJavascriptの代わりに言語の拡張機能を使用しています。これは、私が特にここで探していたものです(したがって、以前の回答のいずれも、明確であるにもかかわらず、正確にサポートされていないのはなぜですか)私が探していたもの)。

このリンク(http://wekeroad.com/2012/04/05/cleaning-up-deep-callback-nesting-with-nodes-eventemitter)は、私が探していたものの非常に良い例を提供します。また、Trevor Burnhamによる「AsyncJavascript」(http://www.amazon.com/Async-JavaScript-Trevor-Burnham/dp/1475247362)、およびJohnResigによる「SecretsoftheJavaScriptNinja」についても言及する必要があります。およびBearBibeault(http://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X)。これらの本は、私が言及していたこの「コールバック地獄」を回避するエレガントな方法を提供する、クライアントブラウザのカスタムイベントとイベントハンドラの非常に明確な実例を提供します。

于 2013-04-21T05:07:31.573 に答える