0

私はjQueryのコールバックと遅延関数で遊んでいて、なぜこれが機能するのか誰かに教えてもらえないかと思っていました

http://jsfiddle.net/austinbv/QVujr/

  get_each_total = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/search.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };



  get_each_total_broken = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };

$(function () {
    get_each_total(alert("success"));
    get_each_total_broken(alert("fail"));
});

そしてこれはしません

http://jsfiddle.net/austinbv/wzve6/

  get_each_total = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/search.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };



  get_each_total_broken = function(callback) {
    var requests;
    requests = [];
      var url;
        url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";
        return requests.push($.getJSON(url, function(data) {
        }));
    return $.when.apply($, requests).then(function() {
      callback();
    }, function() {
      return alert("There was an error communicating with a remote library, try again in a few");
    });
  };

$(function () {
    get_each_total(function () { alert("success")});
    get_each_total_broken(function () {alert("fail")});
});

ご覧のとおり、唯一の違いは最後の2行にあり、無名関数がコールバックをラップします。どんな洞察もいいでしょう。

4

4 に答える 4

3

このコード:

return requests.push($.getJSON(url, function(data) {
}));

関数を終了します。はcallback呼び出されません。

PSあなたが言っているときthe only difference is an anonymous function wrapping the callback、あなたはあなたがあなたのコードの最初のバージョンでも関数を渡していることを意味します。それは真実ではありません。あなたalert('whatever');は戻ってきたものを何でも渡そうとしています、それはundefinedです!

詳細な説明:

両方の関数(get_each_total、&get_each_total_broken)は、パラメーターが関数であることを期待しています。これは、コードの後半で関数として呼び出そうとしていることから明らかです(callback())。ただし、この行:

get_each_total(alert("success"));

関数をに渡しませんget_each_total。これは、次と同等です。

var returnedFromAlert = alert("success");
get_each_total(returnedFromAlert);

したがって、基本的には、関数に何も渡さないことになりますget_each_total呼び出される前に、すぐにアラートsuccessが表示されます。get_each_total

于 2011-09-02T02:07:43.203 に答える
2
get_each_total(function () { alert("success")});

ここにfunction (){ alert ....、関数オブジェクトを返す があります

 get_each_total(alert("success"));

これは、返されるalert("success")型のオブジェクトであり、関数ではありません。alert()

編集:-コメントに応えて、さらに明確にします。

ブラウザが見たとき

do_something(is_it_complete(arg1, arg2));

次の手順を実行します。

  1. 関数を取得し、is_it_completeそれを引数arg1と呼びますarg2
  2. 関数do_somethingを取得し、上記の結果を引数として呼び出します。

ブラウザに次のように表示された場合:

do_something(function () { is_it_complete(arg1, arg2) });

します:

  1. を呼び出す関数オブジェクトを作成するis_it_complete(arg1, arg2)
  2. 関数do_somethingを取得し、上記のオブジェクトを引数として呼び出します。

編集 3:-最初のコードでは、コードを実行する前にアラートが呼び出されたので、動作しているように見えました。

あなたが持っている:

get_each_total = function(callback) {
     // ... *snip* 
    return requests.push($.getJSON(url, function(data) {}));
    return $.when.apply($, requests).then(function() {
        // ... *snip*
    });
};

2 回目のリターンには到達しません。

編集:-コードを読んだ後、いくつかのヒントを入れると思いました:

var requests;
requests = [];

そのスタイルを冗長に変更します

var requests = [];
var url = " ....";

コールバックに引数を渡さない場合は、ラップしないでください。

.then(function(){ callback();}) 

それは次と同じです:

.then(callback);

コメントで述べたように、あなたのURL

url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=?&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";

する必要があります

url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js?callback=somevalue&apikey=38A260E9D12A4908B1AF9184B691131&q=justin+bieber&window=d";

あるいは:

url = "http://otter.topsy.com/hjhkl/sehjkhhkjhkarch.js"
$.getJSON(url, {
    "callback": "somevalue",
    "apikey": "38A260E9D12A4908B1AF9184B691131",
    "q": "justin bieber",
    "window": "d"
}, function(data){ alert("Got: " + data);});
于 2011-09-02T02:16:01.473 に答える
1

どちらの例も機能しません。(レビュアーへのヒント:彼が話す最後の2行です。)

最初の例では、を呼び出します。これにより、関数が呼び出される前であってもalert()、アラートダイアログが表示されます。 Javascriptはそれを呼び出してアラートを表示し(そして何かが起こったという錯覚を与えます)、呼び出しの結果をに渡します(そして次の関数のアラートでも同じことをします)。結果はnullです。コールバックが呼び出された場合、これによりエラーが発生します。get_each_total()alert()get_each_total()

2番目の例では、関数を宣言し、その関数への参照をに渡します。この関数は、式get_each_total()を介して呼び出すことができますcallback()。関数は、()演算子に応答するものであり、「これを行う」ことを意味します。コードが成功した場合、実際に何かを実行します(アラートを表示します)。

しかし、あなたのコードはそうではありません。フィドルに移動してコンソールを見ると、「リソースのロードに失敗しました:サーバーが500(内部サーバーエラー)のステータスで応答しました」というメッセージが表示されます。 コールバックは成功しないgetJSON()ため、コールバックをトリガーすることはありません。

[編集]@austinbvは、私が何かを逃したと私に指摘しました。500コードは、彼の意図的なテストです。しかし、彼のコードはまだ壊れていget_each_total_broken()ます; return行に置き忘れがあります

return requests.push($.getJSON(url, function(data) {  }));

これはからすぐに戻りますget_each_total_brokenwhen().then()句が呼び出されることはないため、エラー処理は表示されません。最初の例のアラートの即時性は、何かが起こったという幻想を与え続けています。

于 2011-09-02T02:10:52.990 に答える
0

コードには 2 つの問題があります。

1) コードの最後の 2 行: 最初の例では、「alert」メソッドの実行結果を「get_each_total」メソッドと「get_each_total_broken」メソッドの両方に渡しています。2 番目の例は、実行時に "alert" を呼び出す関数を渡しています。2 番目の例は、実行する正しい方法です。

例えば:

function test(v) {
    // do something
    return null;
}

// executes "test" immediately and passes it's result to "someOtherFunction"
someOtherFunction(test(v));
// will pass a function to "someOtherFunction" to be executed later
someOtherFunction(function(){ test("value"); });

2) 両方のメソッドに 2 つの「return」ステートメントがあります。メソッド内で遭遇した最初の「リターン」は、その値を返し、メソッドを終了します。したがって、2 番目の "return" ステートメントは実行されません。結果として、両方のメソッドでの「$.when.apply」への呼び出しは決して実行されません。

于 2011-09-02T02:53:49.987 に答える