簡體   English   中英

在JavaScript中使用Promise-僅命中一次服務器

[英]Using promises in javascript - only hitting the server once

我試圖充分理解諾言的使用及其帶來的好處。 我有一個AJAX調用,可從服務器中獲取大量數據。 現在,我沒有實現承諾,並且只要用戶更改視圖,代碼就會擊中服務器(所有視圖都使用相同的數據,只是外觀相同)。

這是我要補充的承諾:

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而又不會.done服務器? 意思是,由於我將使用相同的數據,並且無法將其保存到全局對象,我該如何實現呢?

跟蹤$.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;
    }
}

注意, jQuery.ajax()返回一個jQuery Promise對象。

第一次成功調用$.ajax()時,定義一個屬性以將數據存儲在實例中。 調用.then().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; eg, `$.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> 

暫無
暫無

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

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