14

jQuery deferredsを正しく使用して、関数内の非同期呼び出しが完了するまで関数の戻りを遅らせ、戻り値を取得するにはどうすればよいですか?

これは私の現在のコードです:

function getFields(page)
{
  var dff = $.Deferred();
  result = {};
  $.ajax( //the async call
    {
      url: page,
      success:
        function (data)
        {
          //work out values for field1 & field 2 from data here
          result = 
          {
            'field1' : field1,
            'field2' : field2
          };
        },
      complete:
        function()
        {
          dff.resolve(result); //my attempt to return the result
        }
    }
  );
  return dff.promise();
}

これで{"field1": "value1"、 "field2":"value2"}を出力したい

var result = getFields('http://something');
console.log(JSON.stringify(result)); 

ただし、resultの値はjQueryオブジェクトのように見えるので、何か間違ったことをしていますが、どうでしょうか。

ありがとう!


PS初心者の質問で申し訳ありませんが、私はdeferredを初めて使用するので、まだ基本的な概念を理解しています。

4

2 に答える 2

13

関数の戻りを遅らせる唯一の方法はgetFields、AJAXasyncプロパティをfalseに設定することです。

   var ajaxPromise = $.ajax(
    {
      url: page,
      async: false  // make the call synchronous
    }
  );

ただし、jQueryのドキュメントには、これは1.8以降では非推奨であると記載されています(つまり、使用は推奨されていません)。

遅延はAJAXを同期化せず、代わりにコールバックと非同期メソッドの操作を容易にします。

あなたが何をしようとしているのかを私が知ることができることから、次のようなことをする方がうまくいくかもしれません:

function getFields(page)
{
  var ajaxPromise = $.ajax( //the async call
    {
      url: page
    }
  );

  var dff = $.Deferred();
  ajaxPromise.then(function(data){

    // Possibly access the loaded data in this function.
    var result = {
      'field1' : field1,
      'field2' : field2
    };

    // Notify listeners that the AJAX call completed successfully.
    dff.resolve(result);

  }, function(){
    // Something went wrong - notify listeners:
    dff.reject(/* possibly pass information about the error */);
  });

  return dff.promise();
}

次に、次のようなpromiseオブジェクトを使用します。

var fieldPromise = getFields('http://something');
fieldPromise.done(function(result){
  console.log(JSON.stringify(result)); 
});

はすぐにオブジェクトをgetFields返しますPromiseが、結果をログアウトする前に、Promiseが解決されるのを待つ必要があることに注意してください。

于 2012-07-12T04:02:08.153 に答える
6

延期の基本的な考え方は次のとおりです。オブジェクトが返され、それを使用して、戻り値が戻ったときに呼び出される関数を定義できます。したがって、次のようなことができます。

function getFields(page)
{
    return $.ajax(page);
}

次に、それを呼び出して、XHR呼び出しが完了したときに呼び出される関数を指定できます。

var jqXHR = getFields("/path/to/call");
jqXHR.done(function (data) { alert(JSON.stringify(data); });

オブジェクトはチェーン可能であるため、次のようにすることができます。

getFields("/path/to/call")
    .done(function (data) { alert(JSON.stringify(data); });

によって返されるjqXHRオブジェクトはDeferred互換オブジェクトであるため、 http:$.ajax //api.jquery.com/category/deferred-object/でドキュメントを読むことができます。

サンプルコードの意味はわかりませんが(実際にはAjax呼び出しを使用していないため)、次のような意味である可能性があります。

function getFields()
{
    var df = $.Deferred();
    window.setTimeout(function () {
        df.resolve({field1: "value1", field2: "value2"});
    }, 1000);
    return df.promise();
}

getFields().done(function (data) { console.log(JSON.stringify(data)); });

これにより、実行後1秒で目的の値が出力されます。

于 2012-07-12T03:57:46.347 に答える