Reputation: 303
I am new to promises and trying to figure out for quite a long time now how to get proper results after the usage of a async network call with which I receive data.
I receive my balance from a exchange and loop through several parameters. When this is finished the holdings
should be returned.
However, I still have to fight the async behaviour. When I run the code without the commented code, the result is []
. If I set a artificial setTimeout, then the returned array holdings
is visible properly.
Can someone tell me please where my mistake lays? I tried to read through docs of mdn and similar problems here on stackoverflow but I am nonetheless stuck.
Thank you guys very much,
Tobias
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);
})
Upvotes: 1
Views: 1958
Reputation: 9964
You're resolving your promise instantaneously but the data is not here yet, as it is happened asynchronously during the callback. Your promise should be resolved after every callback.
What you should do is create a promise for each of the request and then resolve your function with a 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));
});
});
Your getBalance promise will be resolved when all of your promise are resolved. Be cautious though, if one of your promise is rejected, then the whole promise will be rejected.
If it's properly resolved, then the value will be an array of each value of the promises.
Upvotes: 2
Reputation: 191048
Since I'm assuming bittrex.getticker
is async, you should instead just wrap each call into a promise and not try to combine them into one manually.
Here's a loose concept.
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);
Upvotes: 0