相关疑难解决方法(0)

一个接一个地解决承诺(即按顺序)?

请考虑以下以串行/顺序方式读取文件数组的代码.readFiles返回一个promise,只有在按顺序读取所有文件后才会解析.

var readFile = function(file) {
  ... // Returns a promise.
};

var readFiles = function(files) {
  return new Promise((resolve, reject) => 

    var readSequential = function(index) {
      if (index >= files.length) {
        resolve();
      } else {
        readFile(files[index]).then(function() {
          readSequential(index + 1);
        }).catch(reject);
      }
    };

   readSequential(0); // Start!

  });
};
Run Code Online (Sandbox Code Playgroud)

上面的代码可以工作,但我不喜欢按顺序进行递归递归.是否有一种更简单的方法可以重写此代码,以便我不必使用我的奇怪readSequential功能?

最初我试图使用Promise.all,但这导致所有readFile调用同时发生,这不是我想要的:

var readFiles = function(files) {
  return Promise.all(files.map(function(file) {
    return readFile(file);
  }));
};
Run Code Online (Sandbox Code Playgroud)

javascript promise sequential q serial-processing

238
推荐指数
12
解决办法
16万
查看次数

处理嵌套Promise的最佳方法(bluebird)

我在下面有以下承诺链,它看起来很混乱(每个_create*函数返回一个承诺):

return new Promise(function (resolve, reject) {
      _this.database.transaction(function (t) {
        _this._createExternalAccount(payment, t)
          .then(function (externalAccount) {
            return _this._createExternalTransaction(externalAccount, payment, t)
              .then(function (externalTransaction) {
                return _this._createAddress(externalAccount, payment, t)
                  .then(function (address) {
                    return _this._createTransaction(address, payment, t)
                      .then(function (transaction) {
                        return _this._createGatewayTransaction(externalTransaction, transaction, payment, t)
                          .then(function (gatewayTransaction) {
                            t.commit();
                            resolve(bridgePayment);
                          });
                      });
                  });
              });
          })
          .error(function (bridgePayment) {
            t.rollback();
            reject(bridgePayment);
          });
      });
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用Promise函数all(),join()但这些似乎同时运行我无法执行的函数,因为持久化到某些表需要来自先前持久化表的字段.我希望有一些方法让我做以下的事情,但我似乎无法找出如何:

Promise.all(_this._createExternalAccount(payment, t), _this._createExternalTransaction(externalAccount, payment, t), _this._createAddress(externalAccount, payment, t))
    .then(function(externalAccount, externalTransaction, address) {
        // do logic …
Run Code Online (Sandbox Code Playgroud)

javascript promise bluebird

12
推荐指数
1
解决办法
7374
查看次数

AngularJS:链接forEach循环的承诺

我无法绕开承诺.我正在使用Google Earth API对地址进行"浏览".游览只是一个持续大约一分钟的动画,当一个完成时,下一个应该开始.

这是我的游览功能:

var tourAddress = function (address) {
        return tourService.getLatLong(address).then(function (coords) {
            return tourService.getKmlForCoords(coords).then(function (kml) {
                _ge.getTourPlayer().setTour(kml);
                _ge.getTourPlayer().play();

                var counter = 0;
                var d = $q.defer();
                var waitForTour = function () {
                    if (counter < _ge.getTourPlayer().getDuration()) {
                        ++counter;
                        setTimeout(waitForTour, 1000);
                    } else {
                        d.resolve();
                    }
                };

                waitForTour();

                return d.promise;
            });
        });
    }
Run Code Online (Sandbox Code Playgroud)

这看起来效果很好.它启动动画并返回一个在动画完成时解析的promise.现在我有一个地址数组,我想做一个foreach他们:

$scope.addresses.forEach(function (item) {
      tourAddress(item.address).then(function(){
          $log.log(item.address + " complete");
       });
 });
Run Code Online (Sandbox Code Playgroud)

当我这样做时,它们都会同时执行(Google Earth会为最后一个地址执行动画)并且它们都会同时完成.如何在上一个完成之后将它们链接起来?

UPDATE

我用@ phtrivier的帮助来实现它:

 $scope.addresses.reduce(function (curr,next) {
      return curr.then(function(){
            return tourAddress(next.address)
      });
  }, Promise.resolve()).then(function(){ …
Run Code Online (Sandbox Code Playgroud)

javascript promise angularjs angular-promise

7
推荐指数
1
解决办法
6166
查看次数

如何在 JavaScript 中将 promise 链接在一起

我试图链接一系列Promises 以便第二个承诺将在第一个解决之后开始,依此类推。我不明白我怎么不能让它正常工作。

这是我的演示代码:

    const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'a'); });
    const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'b'); });
    const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 5000, 'c'); });

    promise1.then(val => {
      console.log('promise 1', val);
      promise2.then(val2 => {
        console.log('promise 2', val2);
        promise3.then(val3 => {
          console.log('promise 3', val3);
        });
      });
    });
Run Code Online (Sandbox Code Playgroud)

所以我对这段代码的期望是这样的:

--- 5 seconds passes ---
// console outputs: 'promise 1a'
--- 5 seconds passes ---
// console …
Run Code Online (Sandbox Code Playgroud)

javascript promise es6-promise

1
推荐指数
1
解决办法
61
查看次数