繁体   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