簡體   English   中英

如何轉換為使用Promises和Q庫

[英]How to convert to using Promises and Q Library

我們的應用程序正在增長,我們需要將客戶端腳本重構為更簡潔,更精簡和更易於維護。 我正在嘗試使用一個利用Q庫的小模塊進行諾言鏈接。

如您所見,我需要將一些返回值從初始函數傳遞回諾言鏈的其余部分。 有人可以幫我理解我需要做什么才能使第一個函數正確地作為承諾返回嗎? 然后解釋一下鏈條?

這是我的出發點:

var promise = new Q.Promise(generateMoveRequest)
    .then(function (id) {
       var woNum = 12345;
       return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
          return moveRequestInit(result, true);
        } else { 
          throw new Error('Template not loaded');
        }
    }).catch(function (err) {
        console.log(err);
    });

生成移動請求:

generateMoveRequest: function () {
        $.ajax({
            method: "GET",
            url: window.contextPath + '/api/settings/getjson',
            data: {name: "the_name"},
            success: function (data) {
                if (data.length) {
                    var id = $.parseJSON(data).Parent;                                          
                    return id;
                }
            },
            error: function (xhr, textStatus, errorThrown) {
                console.log("xhr: ", xhr);
                return null;
            }
        });
    }

布局初始化:

layoutInit: function (num, id, appendLayout) {
    $.ajax({
            method: "GET",
            url: window.contextPath + '/some/url',
            data: {num: num, id: id},
            success: function (data) {
                return layoutInit.callback(data, appendLayout);
            },
            error: function (xhr, textStatus, errorThrown) {
                console.log("xhr: ", xhr);
            }
        });
    },
    callback: function (data, appendLayout) {
        if (data && data.toString().toLowerCase() !== "blank") {
            if (appendLayout) {
                $(data).insertBefore($("#detailsection"));
            } else {
                $("#detailsection").html(data);
            }                               
        } else {
            $("#detailsection").html('');
        }
    },

generateMoveRequest函數將執行,但是鏈永遠不會繼續進行。 沒有.then()執行和layoutInit永遠不會被調用。

我正在使用Q庫,但是某些示例似乎忽略了如何啟動/創建Promise或將初始功能轉換為Promise。

有人可以在這里解釋我的錯還是為我提供一個清晰的例子?

承諾的jQuery實現未遵循A +標准,因此您最好使用Q。

Promise必須接收帶有2個參數的函數- resolvereject -這也是函數(請記住Javascript是一種功能語言)。 成功時必須調用resolve函數,而在錯誤時必須reject 無論傳遞給這些函數的內容如何,​​都將在then()catch()回調中提供。

長話短說,像這樣重寫您的代碼:

var generateMoveRequest = function (resolve, reject) {
  $.ajax({
    method: "GET",
    url: window.contextPath + '/api/settings/getjson',
    data: {name: "the_name"},
    success: function (data) {
      if (data.length) {
        var id = $.parseJSON(data).Parent;
        resolve(id);
      } else {
        reject({message: 'Data not received'})
      }
    },
    error: function (xhr, textStatus, errorThrown) {
      reject({message: errorThrown})
  }
  });
}

var promise = new Q.Promise(generateMoveRequest)
    .then(function (id) {
       var woNum = 12345;
       return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
          return moveRequestInit(result, true);
        } else {
          throw new Error('Template not loaded');
        }
    }).catch(function (error) {
      console.log(error.message)
    });

以后進行編輯-請參閱摘要以了解Promises的工作方式:

// any number of params
function willPerformAnAsyncOperationAndReturnAPromise(firstParam, secondParam, thirdParam) {
  var promise = new Q.Promise(function (resolve, reject) { // always resolve & reject
    // perform an async operation, like waiting one second
    window.setTimeout(function () {
      if (firstParam !== 0) {
        // if the 1st param is not 0, it's a success
        resolve ({
          first: firstParam,
          second: secondParam,
          third: thirdParam
        })
      } else {
        reject({message: 'The first param must not be null'})
      }
    }, 1000)
  })

  return promise
}

willPerformAnAsyncOperationAndReturnAPromise(1, 2, 3)
  .then(function (data) {
    console.log(data)
  })
  .catch(function (error) {
    console.log(error)
  })

willPerformAnAsyncOperationAndReturnAPromise(0, 2, 3)
  .then(function (data) {
    console.log(data)
  })
  .catch(function (error) {
    console.log(error)
  })

一些問題:

  • 您的函數generateMoveRequest應該返回一些信息: $.ajax返回一個promise(它具有then方法),因此您可以返回它;

  • 您無需創建新的Promise,因為generateMoveRequest返回一個Promise。 這樣,您可以避免promise構造函數的反模式

建議的代碼:

generateMoveRequest: function () {
    return $.ajax({
        method: "GET",
        url: window.contextPath + '/api/settings/getjson',
        data: {name: "the_name"},
    }).then(function (data) {
        if (data.length) {
            var id = $.parseJSON(data).Parent;                                          
            return id;
        }
    }).catch(function (xhr, textStatus, errorThrown) {
        console.log("xhr: ", xhr);
        return null;
    })
}

var promise = generateMoveRequest()
    .then(function (id) {
        var woNum = 12345;
        return layoutInit(woNum, id, true);
    }).then(function (result) {
        if (result) {
           return moveRequestInit(result, true);
        } else { 
           throw new Error('Template not loaded');
        }
    }).catch(function (err) {
        console.log(err);
    });

暫無
暫無

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

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