簡體   English   中英

將RSVP.js中的promise數組與jQuery的$ .ajax集成在一起

[英]Integrating array of promises from RSVP.js with jQuery's $.ajax

回復: https//github.com/tildeio/rsvp.js

將RSVP.js與jQuery的$ .ajax集成的最佳方法是什么? 在做了一些閱讀和研究之后,我看到Ember正在積極開發一個包裝器... https://github.com/emberjs/ember.js/pull/4148

有這種使用承諾經驗的人嗎?

我正在使用RSVP.js因為我正在通過.all()方法處理動態的promises數組。

來自數組的每個promise都有自己的承諾,一旦遞歸完成對函數數據的輪詢,就會實現。 我在考慮如何構建代碼時遇到問題。

如果您感興趣的話,用例是我正在向我的API發送一個AJAX請求,以獲取與特定資源相關的報告,該報告返回一個URL端點列表,該端點應該針對其子資源的更多報告數據。 然后,每個資源返回一個JSON對象,其中包含特定日期的報告數據和另一個帶有params的URL,用於第二天(或一組天)。 然后,這將繼續輪詢來自同一端點的“next”數據,直到沒有任何內容為止。

提前感謝任何可以提供幫助的人!

此外,如果您有關於如何格式化此代碼的任何指導,以使其更具可讀性和可維護性,我很樂意聽到。

碼:

url = "http://localhost:3000/api/foo_resources/1/reports/bar"

var headers = {
    "Accept": 'application/vnd.xps+json; version=1', // Headers for API access
    "X-User-Email": 'example@company.com',
    "X-User-Token": '1234abcd',
}

$.ajax({
    type: 'GET',
    url: url,
    headers: headers,
    dataType: 'json',
    xhrFields: {
        withCredentials: true
    }
}).then(function(response) {

    // the ajax request would return a long list of bucket like this with endpoints to hit {
    // {
    //   "buckets": [
    //     "http://localhost:3000/api/foos_nested_resources/1/reports/bar"
    //     "http://localhost:3000/api/foos_nested_resources/2/reports/bar"
    //     "http://localhost:3000/api/foos_nested_resources/3/reports/bar"
    //   ]
    // }

    var promises = response.buckets.map(function getReportData(bucket) {

        return new RSVP.Promise(function(resolve, reject) {
            var recursiveRequest = function(bucket) {
                $.ajax({
                    type: 'GET',
                    url: bucket,
                    headers: headers,
                    dataType: 'json',
                    xhrFields: {
                        withCredentials: true
                    }

            // This is the report that comes back, obviously truncated significantly for this example
            // {
            //   reports: [
            //     { id: 1, datapoint_a: 5438, datapoint_b: 1389 },
            //     { id: 2, datapoint_a: 4336, datapoint_b: 2236 }
            //   ],
            //   next: "http://localhost:3003/api/nexted_foo_resources/1/reports/bar?ends=2014-02-06&starts=2014-01-24"
            // }

                }).done(function(response) {
                    $.merge(reports, response.reports); // I could use concat here but I prefer readability

                    if (response.next) {
                        recursiveRequest(response.next);
                    } else {
                        resolve(reports);
                    }
                }).error(function(error) {
                    reject(error);
                });
            };

            recursiveRequest(bucket);
        });
    });

    RSVP.all(promises).then(function(data) {
        console.dir(data);
    }).catch(function(error) {
        console.dir(error);
    })
})

有一點需要注意,我沒有測試過這段代碼(因為我沒有使用你的API),我認為以下內容更接近於RSVP的慣用法:

var initialUrl = "http://localhost:3000/api/foo_resources/1/reports/bar";

var headers = {
  "Accept": 'application/vnd.xps+json; version=1', // Headers for API access
  "X-User-Email": 'example@company.com',
  "X-User-Token": '1234abcd',
};

function rsvpAjax(opts){
  return new RSVP.promise(function(resolve, reject){
    var defaultOpts = {
      type: 'GET',
      headers: headers,
      dataType: 'json',
      xhrFields: {
        withCredentials: true
      }
    };
    $.ajax($.extend({}, defaultOpts, opts, {
      success: function(json) {
        resolve(json);
      },
      error: function(jqXhr, textStatus, errorThrown){
        reject({ jqXhr: jqXhr, textStatus: textStatus, errorThrown: errorThrown});
      }
    }));
  });
}

function requestBucket(bucket){
  return rsvpAjax({ url: bucketUrl }).then(bucketResponseProcessor(bucket));
}

function bucketResponseProcessor(bucket){
  return function(response){
    $.merge(bucket.reports, response.reports);
    if (response.next) {
      bucket.url = response.next;
      return requestBucket(bucket);
    } else {
      return bucket.reports;
    }    
  };
}

rsvpAjax({ url: initialUrl }).then(function(response) {
  return RSVP.all(response.buckets.map(function(bucketUrl){
      var bucket = { url: bucketUrl, reports: [] };
      return requestBucket(bucket).then(processBucketResponse);
  }));
}).then(function(reports) {
  console.dir(data);
}).catch(function(error) {
  console.dir(error);
});

我想你要找的是Ember.RSVP.Promise.cast()

這些示例使用$ .getJSON()顯示它,但它應該適用於任何jQuery Ajax方法,因為它們都返回Deferred對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM