javascript - While 循环中的 Promise,其中 while 的条件基于 Promise 的结果

标签 javascript es6-promise

我需要执行一个不确定的循环,其中循环的条件将基于循环内从数据库获取一些数据的 promise 的响应。该循环应该在一个 Promise 中完成,然后返回从数据库中提取的记录的总列表。这与现实世界的示例有所简化,但尝试提供一些基本代码来演示我本质上想做的事情。

对 getLinkedEntities 的调用会传入一个实体,并根据链接实体 ID 开始循环,在该循环中返回链接实体,然后从原始 Promise 返回。

我遇到的问题是,由于 Promise 的异步性质,在 while 循环内调用 getElement 时,它永远不会解决,因为函数会继续并陷入连续循环中。

希望这段代码能够很好地描述我想要做的事情,即最终得到一个链接实体的数组,但是如何以允许所有 promise 返回的同步方式完成它?

   function getLinkedEntities(startEntity) { 
        return new Promise(function (resolve, reject) {

            var linkedEntities = [];
            var entityId = startEntity.id;
            var someOtherId = startEntity.linkedentityid;

            var stopLoop = false;

            do {

                getElement(someOtherId).then(function (entity) {
                    linkedEntities.push(entity)
                    entityId = entity.id;
                    someOtherId = entity.linkedentityid;
                    stopLoop = entity.linkedentityid === null ? 1 : 0;
                });

            }
            while (!stopLoop);

            resolve(linkedEntities);

        });
    }

    function getElement(id) {
        return new Promise(function (resolve, reject) {
            // go to database and get an entity
            resolve(entity);
        });
    }

    getLinkedEntities(someEntity).then(function (response) {
        // do somethign with linkedEntities
    });

最佳答案

不使用async / await ,您可以做的是创建一个调用自身的内部函数。

例如。

  ...
  function getNext() {
     return getElement(someOtherId).then(function (entity) {
       linkedEntities.push(entity)
       entityId = entity.id;
       someOtherId = entity.linkedentityid;
       stopLoop = entity.linkedentityid === null ? 1 : 0;
       if (stopLoop) return resolve(linkedEntities);
       else return getNext();
     });
  }
  //boot strap the loop
  return getNext();
}

基本上这只是不断调用getNext直到stopLoop设置,然后解析 linkedEntities ,如果不是,则调用 getNext再次。 IOW:正是您的 while 循环正在执行的操作。

下面是一个使用这个想法的工作片段,而不是 getElement ,我已经换成了 sleep promise 。基本上 fill 是一个在每次数组推送之间等待 500 毫秒的数组。

function sleep(ms) {
  return new Promise(function (resolve) {
    setTimeout(resolve, ms);
  });
}

function test() {
  var ret = [];
  function getNext() {
    return sleep(500).then(function () {
      if (ret.length >= 10) {
        return ret;
      } else {
        console.log('tick: ' + ret.length);
        ret.push(ret.length + 1);
        return getNext();
      }
    });
  }
  return getNext();
}

test().then(function (r) {
  console.log('Resolved with ->');
  console.log(r.join(','));
});

关于javascript - While 循环中的 Promise,其中 while 的条件基于 Promise 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60743065/

相关文章:

javascript - ngTouch ngClick 不冒泡

javascript - JavaScript 中的 for in 循环

javascript - 在 promise 链中混合变量

JavaScript ES7 - 在页面顶部调用异步函数,在底部等待

ecmascript-6 - promise es6 和 superagent

javascript - 数据集导入后添加HTML元素

javascript - 为什么不显示图像?

javascript - jQuery - 无法在初始化之前调用对话框上的方法

javascript - for 循环内的 Promise