在forEach循环之后承诺

时间:2018-01-05 15:16:13

标签: javascript asynchronous foreach es6-promise

我是承诺的新手,并且试图在很长一段时间内弄清楚如何在使用我接收数据的异步网络调用后获得正确的结果。

我从交换中获得余额并循环访问几个参数。完成后,应返回holdings

但是,我仍然要打击异步行为。当我在没有注释代码的情况下运行代码时,结果为[]。如果我设置一个人工setTimeout,则返回的数组holdings可以正常显示。

有人可以告诉我,我的错误在哪里?我尝试在stackoverflow上阅读mdn和类似问题的文档,但我仍然坚持。

非常感谢你们,

托拜厄斯

const bittrex = require('node.bittrex.api');
const {key, secret} = require('./key')

let getBalance = new Promise((resolve, reject) => {
  let holdings = [];
  bittrex.getbalances( function( data, err ) {
    if (err) {
      reject(err);
    }
    data.result.forEach(coin => {
      if (coin.Balance !== 0) {
        let market = `BTC-${coin.Currency}`;
        if(coin.Currency === 'BTC') market = `USDT-BTC`;
        bittrex.getticker( { market : market}, function( ticker, err ) {
          if (err) {
            reject(err);
          }
          holdings.push({
            Coin: coin.Currency,
            Balance: coin.Balance,
            Last: ticker.result.Last
          });
        })
      }
    });
  });
  resolve(holdings);
})

getBalance
// .then((holdings) =>{
//   return new Promise((resolve, reject)  => {
//     setTimeout(() => {
//       resolve(holdings);
//     }, 10000)
//   })
// })
  .then((holdings) => {
        console.log(holdings);
  })

2 个答案:

答案 0 :(得分:1)

您即时解决了您的承诺,但数据尚未到位,因为它在回调期间是异步发生的。你的承诺应该在每次回调后得到解决。

您应该做的是为每个请求创建一个承诺,然后使用Promise.all解析您的功能

const bittrex = require('node.bittrex.api');
const {key, secret} = require('./key')
let getBalance = new Promise((resolve, reject) => {
  let holdings = [];
  bittrex.getbalances( function( data, err ) {
    if (err) {
      reject(err);
    }
    const promises = data.result.map(coin => new Promise((resolve, reject) => {
      if (coin.Balance !== 0) {
        let market = `BTC-${coin.Currency}`;
        if(coin.Currency === 'BTC') market = `USDT-BTC`;
        bittrex.getticker( { market : market}, function( ticker, err ) {
          if (err) {
            reject(err);
          }
          resolve({
            Coin: coin.Currency,
            Balance: coin.Balance,
            Last: ticker.result.Last
          });
        })
      }
    });

    resolve(Promise.all(promises));
  });
});

当您的所有承诺得到解决后,您的getBalance承诺将得到解决。但是要小心,如果你的一个承诺被拒绝,那么整个承诺将被拒绝。

如果它已正确解析,那么该值将是承诺的每个值的数组。

答案 1 :(得分:0)

因为我假设bittrex.getticker是异步的,所以你应该将每个调用包装成一个promise,而不是尝试将它们组合成一个。

这是一个松散的概念。

function getTicker(...) {
    return new Promise(function(resolve, reject) {
        bittrex.getticker(..., function(ticker, error) {
            if (error) { reject(error); }
            else { resolve(ticker); }
        });
    });
}

var lotsOfPromises = data.result.map(function(coin) {
    return getTicker(...).then(function(ticker) {
        return { yourOutputdata }
    });
});

Promise.all(lotsOfPromises);