Here is a function to find mx records of a service and i need to save the one value(with the lowest priority) to make a request to it. How can I save and return this value?
const dns = require('dns');
const email = '...#gmail.com'
let res = email.split('#').pop();
function getMxRecords(domain) {
return new Promise(function(resolve, reject) {
dns.resolveMx(domain, function(err, addresses) {
if (err) {
//console.log(err, err.stack)
resolve(null);
} else {
//console.log(addresses);
let copy = [...addresses];
//console.log(copy);
let theone = copy.reduce((previous, current) => {
if (previous.priority < current.priority) {
return current;
}
return previous;
});
resolve(theone);
}
});
});
}
let a = getMxRecords(res);
console.log(a);
Yeah, so i need to export this module to make a request to it like below;
let socket = net.createConnection(25, request(email), () => {})
so for this my function should request me or array or object with only one value, when i'm trying it doesn't work, i always get this:
Promise { } //HERE IS RETURN FROM MY FUNCTION (WITH .THEN)
Error in socket connect ECONNREFUSED 127.0.0.1:25
A Promise is mostly an asynchronous call. It returns an Promise-Object that will resolve or reject the Promise. To access the result, you will call some functions:
function getMxRecords(domain) {
return new Promise(function(resolve, reject) {
dns.resolveMx(domain, function(err, addresses) {
if (err) {
//console.log(err, err.stack)
resolve(null);
} else {
//console.log(addresses);
let copy = [...addresses];
//console.log(copy);
let theone = copy.reduce((previous, current) => {
if (previous.priority < current.priority) {
return current;
}
return previous;
});
resolve(theone);
}
});
});
}
getMxRecords(res)
.then(yourResolveValueProvided => {
// Your code if the promise succeeded
})
.catch(error => {
// Your code if the promises reject() were called. error would be the provided parameter.
})
Related
I have a module for nodejs where i search mx records of email service, then i call a reduce to find the one with lowest priority (i will connect to this mx record to send a message) and then i need to save this value (exactly smtp.gmail.com) and pass it into my another module. What do i do wrong ?
const dns = require('dns');
async function getMX() {
return new Promise(function (resolve, reject) {
dns.resolveMx('gmail.com', function (err, addresses) {
if (err) {
resolve(null);
}
else {
resolve(addresses);
}
});
}).then(listOfMX => { // here i'm looking for value with lowest priority
return arr = listOfMX.reduce((previous, current) => {
if (previous.priority < current.priority) {
return previous
}
return current;
})
}).then(response => {
console.log(response[0]);
return response.exchange; // i get {exchange:"smtp.aspko.com", priority: 5}, and from this i return only the exchange
}).catch(err => {
console.log(err);
});
};
async function f() { // async function to solve the Promise <pending>
const response = await getMX();
console.log(response)
};
f(); // here i call the main function
Anyway i still see or Promise or undefined and i can't just add a return in async function f(), which will solve my problem (when i will call f() it should return me the one value, but instead i see undefined)
In c# I would write something like this:
bool HasRole(string userName, string[] groupNames)
{
var ad = new ActiveDirectory();
return groupsNames.Any(groupName => ad.IsUserInGroup(userName, groupName);
}
and then just
if (HasRole("UserName", new[] {"group1", "group2"}))
//do something
in javascript it looks like all things are doing asynchronously, I've read about promises and so on, and tried this:
const ActiveDirectory = require('activedirectory2');
const Promise = require('promise');
const globals = require('./globals');
const activeDirectory = new ActiveDirectory(globals.AdConfig);
hasRole(msg, ...groupNames) {
if (groupNames == null || groupNames == undefined || groupNames.length == 0)
return false;
let promises = [];
groupNames.forEach(groupName => {
let promise = new Promise((resolve, reject) => {
activeDirectory.isUserMemberOf(msg.envelope.user.name, groupName, function (err, isMember) {
if (err) {
reject(err)
}
resolve(isMember);
});
});
promises.push(promise);
});
//I don't clearly understand how I can return promise result only or promise with the right result
let hasRole = false;
promises.forEach(promise => promise.done(result => {
if (result)
hasRole = result;
}));
return hasRole;
So how can write something like:
if (hasRole(msg, 'group1', 'group2'))
//do something...
I suppose I should return promise but how I can do it if i need to check multiple groups?
UPDATE
I wrapped the forEach loop in promise:
return new Promise((resolve, reject) => {
promises.forEach(promise => promise.done(result => {
if (result)
return resolve(result);
}));
and then:
hasRole(msg, 'group1', 'group2').done(result => {
if (result)
//do...
});
May there is another way?
Found a solution. Promises.all is what i needed.
Result code:
hasRole(msg, ...groupNames) {
let promises = [];
groupNames = groupNames.filter(x => x.trim().length > 0);
if (groupNames == undefined || groupNames.length == 0)
{
promises.push(new Promise.resolve(false));
return Promise.all(promises);
}
groupNames.forEach(groupName => {
let promise = new Promise((resolve, reject) => {
activeDirectory.isUserMemberOf(msg.envelope.user.name, groupName, function (err, isMember) {
if (err) {
reject(err)
}
resolve(isMember);
});
});
promises.push(promise);
});
return Promise.all(promises);
}
I want to save sqlite3 row values into an array. I followed what was discussed here:
Can't put rows into array using sqlite3 on Node.js
However when I console.log my would-be-array records, I obtain:
console.log(records) => an array with values [1,1,2]
console.log(records[1]) => undefined
There must be a mistake in my understanding of what's going on. What is wrong?
Full code below:
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('src/db/ksbib.db', (err) => { if (err) { return console.log(err.message); } });
let result = [];
let records = [];
function catchResult (err, row)
{
if (err) { return console.log(err.message); }
else { return result.push(row.objektid); }
}
function getData ()
{
return new Promise ((resolve, reject) =>
{
db.parallelize ( () =>
{
db.each(sqlTitel(param), catchResult);
db.each(sqlAutor(param), catchResult);
});
resolve(result);
})
}
async function res ()
{
records = await getData();
console.log(records);
console.log(records[1]);
return records;
};
let x = res();
console.log(x);
The contradiction between console.log(records) and console.log(records[1]) does not exist in the commandline. It seems that some other code interferes in the console.
Moreover, the promise as implemented above resolves with the emtpy result-array before the database request is finished. One can introduce a timeout to play with the code.
In order to resolve the promise after the database request, one should resolve it in the callback function of the request. That's also the reason why db.all is much easier to handle than db.each.
Instead of a series of database requests one can then use a series of promises. Thereby it is important to wait for every single promise to be resolved (just coupling them like this return await sqr(sqlTitle(y), []).then(sqr(sqlAuthor(y), [])) gives no unique result). The result-array is completed bit by bit.
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('ksbib.db', (err) => { if (err) { return console.log(err.message); } });
let result = [];
let p;
function sqr (sql, x)
{
return new Promise(function (resolve, reject)
{
db.all(sql, x, (err, rows) =>
{
if (err) {
reject(err);
} else {
rows.forEach( (row) => {result.push(row.objektid)} );
resolve(result);
}
});
});
}
( async () =>
{
p = await sqr(sqlTitle(y), []);
p = await sqr(sqlAuthor(y), []);
return p; //the final result
})();
I have two functions that return promise. The first one provide host value, and the second one use the host value to get IP address. I can see that the first function is running without any issue. But looks like the callback function side getHostIps is not executed at all. Not sure why it happens....what's wrong with my promise function?
my promise chain:
getHostedZoneId(dns)
.then(hostZoneId => {
getHostIps(dns, hostZoneId);
})
.then(hostIps => {
logger.Info(hostIps); //hostIps is undefined
})
.catch(err => logger.error(err));
getHostedZoneId:
var getHostedZoneId = function(dns) {
var params = {
DNSName: dns,
};
return new Promise((resolve, reject) => {
findHostZoneByDNS(params, function(err, data) {
if(err) {
reject(err);
}
else {
resolve(data);
}
});
});
}
getHostIps:
var getHostIps = function(dns, hostZoneId) {
var params = {
HostedZoneId: hostZoneId,
StartRecordName: dns,
};
return new Promise((resolve, reject) => {
findHostIps(params, function(err, data) {
//logger.info("get there");
if(err) {
reject(err);
}
else {
resolve(data);
}
});
});
}
I logged hostIps and err and data, all of them are defined. So I am sure that the callback function inside promise is not executed. But not sure how to fix it.
Any feedback is appreciated! Thanks!
You have to return the promise from your then statement to complete the chain.
getHostedZoneId(dns)
.then(hostZoneId => {
return getHostIps(dns, hostZoneId); // Add return
})
.then(hostIps => {
logger.Info(hostIps);
})
.catch(err => logger.error(err));
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);
})
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.
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);