1

非同期プログラミングでは、次のような多くのコールバックを使用します。

var running = function(){
    do_sth();
    $.post("/xxx", function(data){
        do_sth2();
        $.get("/ttt", function(data){
            do_sth3();
        }
    }
}

そして私は物事はこのようになるべきだと思います:

var running = do_async(function(){
    do_sth();
    var data = $.post("/xxx");
    do_sth2();
    data = $.get("/ttt");
    do_sth3();
});

どうやってやるの?

これに関するプロジェクトがあります:https ://github.com/JeffreyZhao/jscex

このプロジェクトはそれほど使いやすいものではないと思います(実装はソースコードを解析することによって行われます)

将来的には、これについてネイティブのJavaScriptサポートがありますか?


私はこれについていくつかの調査を行い、参考のためにここでいくつかの議論とライブラリを見つけました:

https://github.com/JeffreyZhao/jscex

Coffeescriptを延期する https://github.com/jashkenas/coffee-script/issues/350

Coffeescriptにマージ: https ://github.com/jashkenas/coffee-script/issues/350

tamejsライブラリ http://tamejs.org/

stratifiedjs http://onilabs.com/stratifiedjs

kaffeine http://weepy.github.com/kaffeine/

これに関するwikiページ:http: //en.wikipedia.org/wiki/Continuation-passing_style


それをサポートするライブラリを追加するのは簡単ではありませんが、

おそらく将来的には、javascriptは「defer」キーワードを追加するでしょう。


同じ質問:非同期JavaScript関数をラップして同期させるためのパターン

4

4 に答える 4

1

コールバックは Javascript の重要な部分です。Javascript はそれらを利用するように設計されています。ある種の「シンクロナイザー」を手に入れることはないと思います。それどころか、Workers.

これらすべてのコールバックに困惑している場合は、できるだけ早く慣れる必要があります。あなたは大丈夫です、私を信じてください。

とにかく、AJAX リクエストは同期的に実行できますが、これによりスクリプトの実行が停止することに注意してください。

于 2012-05-23T00:28:25.977 に答える
1

Promisesを調べているかもしれません。利用可能な実装がいくつかあります。 commonjs.orgを参照してください。それらはすべて連鎖を許可するため、次のようにコードを記述できます。

function running(){
    return do_sth()
       .then($.post.bind($, "/xxx"))
       .then(do_sth2)
       .then($.get.bind($, "/ttt"))
       .then(do_sth3);
    // returns a Promise to run all these tasks
    // ...or:  a Promise for the result of the last of the chained tasks
}

jQuery を使用している場合、これは遅延機能に既に組み込まれています(ただし、私のお気に入りの Promise 実装ではありません)。

function running(){
    do_sth();
    return $.post("/xxx")
      .then(do_sth2)
      .then(function(){ 
        $.get("/ttt")
          .then(do_sth3);
      });
}
于 2012-05-23T00:47:32.990 に答える
1

この非同期コールバックの動作は設計によるものであり、不運な見落としではありません。これは、Node.js コミュニティ (Node は同様のイベント ループを使用します) でかなり頻繁に取り上げられるものであり、そこではファイバーやスレッドなどに基づいて多くの代替手段が開発されます。また、これらの代替手段の多くをカバーしています。

編集: Node フォーラムの非同期ライブラリに関する別のトピック。

  • async - 非同期制御フロー、いくつかの機能的な砂糖
  • after - 非同期制御フロー、いくつかの機能的な砂糖
  • step - シンプルなフロー制御

寄稿者の中には、それらを作成したり、他のフロー制御ライブラリを作成したりした人もいました。

その他最近読んだもの

ただし、そのような動作が特に必要な場合 (たとえば、@MaxArt が言及したブラウザー内のワーカー、またはコードがマルチスレッド (. ) モデル) これらのソリューションのほとんどは、実際にはその下にあるシングル スレッド ループであるためです。名前付き関数を渡す/呼び出すことで、あまりにも厄介なネストを避けることができます。

function a() {
  somethingAsync(function (val) { b(val); });
}

function b(val) { ... }
于 2012-05-23T01:19:10.517 に答える
0

JavaScript は完全にシングルスレッドであるため、非同期コードを同期する方法はまったくありません。

コツをつかむために練習することをお勧めします。機能を試してみてもいいかもしれませんsetTimeout。コールバックを渡して"Hello, World!"、コンソールに表示するようにします。また、最後のパラメーターとして数値 0 を渡します。

ただし、そうは言っても、ライブラリを使用して非同期コードを「きれいにする」ことができます。

特に私のお気に入りの1つがあります。これは async.js と呼ばれます。私はこれを常に使用して、深くネストされた非同期呼び出しをより同期的に見えるようにします (つまり、MongoDB クエリ)。

async.waterfall([

  // Call to the first asynchronous call...
  function (callback) {
    setTimeout(function () {
      callback(null, "Hello, World!");
    }, 0);
  },

  // That needs to make another...
  function (callback, message) {
    console.log(message);
    setTimeout(function () {
      callback(null, "It's a nice day!");
    }, 0);
  },

  // Another...
  function (callback, message) {
    console.log(message);
    setTimeout(function () {
      callback(null, "Bye, now!");
    }, 0);
  },

  // And another.
  function (callback, message) {
    console.log(message);
  }

]);

// Without making the entire thing hopelessly nested deeply.
于 2012-05-23T01:45:49.340 に答える