在javascript中使用promises - 只打一次服务器

时间:2016-12-09 23:59:15

标签: javascript jquery ajax

我正在努力充分了解承诺的用法及其带来的好处。我有一个AJAX调用,从服务器抓取一堆数据。现在我没有实现promises,并且代码在用户更改视图的任何时候点击服务器(所有使用相同的数据,只是它看起来的样子)。

以下是我要添加的承诺:

function feedData(arr){
     //data being initialized
    this.initData();
}

feedData.prototype = {
    constructor: feedData,
    getData:function(){
        return $.ajax({
           url: 'php/getData.php',
           dataType: 'json',
           data: {
                //data being sent over
           }
        });
    },
    initData:function(){
        this.getData()
        .done(function(result){
            console.log(result.length);
        })
        .fail(function(x){
            console.log(x);
        });
    },
    ....
}

我可能没有完全理解这里的asyc行为。我希望做的是从getData获取结果,并填充一个充满数据的对象,每当用户更改视图时都会调用这些数据。从我读过的所有内容来看,这不是用于什么承诺。相反,我应该返回一个承诺并再次使用该数据? (也许这是我的思想错误)

所以我的问题是,一旦从AJAX返回来自getData的数据,是否有办法返回承诺并多次使用.done而无需花费时间服务器?这意味着,因为我将使用相同的数据而无法将其保存到全局对象中,我怎么能实现这一目标呢?

2 个答案:

答案 0 :(得分:3)

跟踪$.ajax()返回的承诺。这使得调用只进行一次(在构造函数中),无论您调用getData()的频率如何:

function FeedData() {
    this.data_promise = $.ajax({
        url: 'php/getData.php',
        dataType: 'json',
        data: {}
    });
}

FeedData.prototype = {
    constructor: FeedData,
    getData: function () {
        return this.data_promise;
    }
}

var feed = new FeedData();
feed.getData().then(function () {
    /* .. */
});

您还可以延迟提取,直到您第一次拨打getData()

function FeedData() {
    this.data_promise = null;
}

FeedData.prototype = {
    constructor: FeedData,
    getData: function () {
        if (this.data_promise === null) {
            this.data_promise = $.ajax({
                url: 'php/getData.php',
                dataType: 'json',
                data: {}
            });
        }
        return this.data_promise;
    }
}

答案 1 :(得分:1)

注意,jQuery.ajax()返回一个jQuery promise对象。

首先成功$.ajax()调用定义一个属性来存储实例中的数据。调用.then()时,将$.ajax()的结果作为已解析的Promise分配给对象的属性值。

使用instance.property.then()从对象中检索值。

function feedData(arr) {
  var feed = this;
  this.getData = function() {
    return $.ajax({
           url: 'php/getData.php',
           dataType: 'json',
           data: {
                //data being sent over
           },
            // set `context` : `this` of `$.ajax()` to current `fedData` instance
           context: feed
        });
  };
  this.initData = function() {
    // note `return`
    return this.getData()
      .then(function(result) {
        console.log(result.length);
        // define `this.promise` as a `Promise` having value `result`
        this.promise = Promise.resolve(result);
        return result;
      })
      .fail(function(x) {
        console.log(x);
      });
  }
}

var request = new feedData();
request.initData().then(function(data) {
  console.log(data)
});

// this will not make antoher request
request.promise.then(function(res) {     
  console.log("result:", res)
});

function feedData(arr) {
  var feed = this;
  this.getData = function() {
    // do asynchronous stuff; e.g., `$.ajax()`
    return $.Deferred(function(dfd) {
      dfd.resolveWith(feed, [
        [1, 2, 3]
      ])
    });
  };
  this.initData = function() {
    // note `return`
    return this.getData()
      .then(function(result) {
        console.log(result.length);
        // define `this.promise` as a `Promise` having value `result`
        this.promise = Promise.resolve(result);
        return result;
      })
      .fail(function(x) {
        console.log(x);
      });
  }
}

var request = new feedData();
request.initData().then(function(data) {
  console.log(data)
});
// this will not make another request
request.promise.then(function(res) {      
  console.log("result:", res)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>