簡體   English   中英

如何同步多次調用返回承諾的任何函數

[英]How to synchronously call multiple times any function which is returning promise

例如,我有函數 which Promise.resolve() 如果我已經有任何緩存的實體 id 否則它會調用 ajax 來保留實體 id 然后 Promise.resolve() 新的實體 id

function getReservedEntityId(collectionName) {
        //if (!haveCachedIds) {
            //make ajax call to reserve new ids
            Promise.resolve(newId);
        }
        return Promise.resolve(cachedId);
};

我們如何同步多次調用它來保留多個實體 id?

PS我知道正確的方法是讓這個函數接受參數,該參數將指定實體 id 的計數並相應地發出請求和返回 id,但我想了解我們如何多次同步調用任何返回承諾的函數。

首先, getReservedEntityId()的實現需要正確使用promise。 我建議徹底閱讀 Promise 是如何工作的 特別是,當您的函數執行異步任務時,您需要返回一個承諾,該承諾將根據異步任務的結果解析或拒絕,了解這一點很重要。

function getReservedEntityId(collectionName) {
  if (haveCachedIds) {
    return Promise.resolve(cachedId);
  } else {
    return new Promise((resolve, reject) => {
      // Make the AJAX call and call resolve(newId) in the success callback
      // or call reject(errCode) in the failure callback.
      // The arguments newId and errCode can be any values you like and are
      // the values that get passed to the next link in the promise chain
      //   i.e. the values passed to then() or catch()
    });
  }
}

考慮到這一點,有兩種推薦的方法可以使調用同步:

1)利用承諾鏈

getReservedEntityId(collectionName)
  .then((id) => {
    // Probably want to do something with `id` first...

    return getReservedEntityId(collectionName);
  })
  .then( ... )
  .then( ... );

當然,如果您要將相同的函數傳遞給每個.then()調用,您也可以將其聲明為常規函數,以免重復。

2) 使用異步/等待

這是一個新的 ES2017 特性,仍然沒有得到廣泛支持。 在撰寫本文時,Node.js 支持帶有--harmony標志的 async/await,但大多數瀏覽器不支持 也就是說, async/await 正是為此目的而設計的,將返回 promise 的函數視為同步的。 如果你現在想開始在你的代碼中使用 async/await,通常的做法是使用 JavaScript 轉譯器,它將你的未來就緒 JavaScript 轉譯為所有主要瀏覽器都支持的代碼。

這是您使用 async/await 的方式:

(async function someAsyncFunction {
  const id1 = await getReservedEntityId(collectionName);
  const id2 = await getReservedEntityId(collectionName);
  const id3 = await getReservedEntityId(collectionName);
                          .
                          .
                          .
})();

語法比承諾鏈更好,更易讀,因為它就是為這個目的而設計的。 請注意,我在此處使函數自調用,以便它與您的行為相匹配,而無需進行額外的函數調用。 但是您可以使用和調用用async function函數定義的async function ,就像任何其他返回承諾的async function一樣。

@fvgs 你的回答也是正確的。 但這里是完整的解決方案,我面臨的挑戰是維護 ReserveIds 列表,這是對每個 getReservedEntityId 調用的響應。

getEntityIds: function (entity, count) {
    if (!count || count == 1)
        return Utils.getReservedEntityId(entity);

    var promise = new Promise(function(resolve, reject) {
        var result = [];
        var chain = Utils.getReservedEntityId(entity);
        var callBack = function CB (result, newId) {
            result.push(newId);

            if (result.length == count)
                resolve(result);
            else
                return Utils.getReservedEntityId(entity);
        }.bind(null, result);

        for (var i=1; i <= count; i++) {
            chain.then(callBack);
        }

        chain.catch(reject);
    });

    return promise;
}

暫無
暫無

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

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