Reputation: 23
I'm trying convert callback functions from nodeS7 API to promises. There is the code with callback, whit work correctly:
var nodes7 = require('nodes7');
var conn = new nodes7;
var doneReading = false;
var doneWriting = false;
var variables = {
TEST5: 'DB1,REAL4',
};
conn.initiateConnection({port: 102, host: '192.168.0.2', rack: 0, slot: 1}, connected);
function connected(err) {
if (typeof(err) !== "undefined") {
// We have an error. Maybe the PLC is not reachable.
console.log(err);
process.exit();
}
conn.setTranslationCB(function(tag) {return variables[tag];});
conn.addItems(['TEST5']);
conn.readAllItems(valuesReady);
}
function valuesReady(anythingBad, values) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
console.log(values); // return {'TEST5': 23.5}
doneReading = true;
if (doneWriting) { process.exit(); }
}
Now I'm trying do something like that:
var nodes7 = require('nodes7');
var conn = new nodes7;
function readVal(){
return new Promise((resolve) => {
conn.initiateConnection({port: 102, host: '172.16.85.10', rack: 0, slot: 1}, resolve);
})
}
function connected() {
conn.addItemsNow(['DB12,REAL140']);
return new Promise((resolve) => {
conn.readAllItems(resolve);
});
}
async function testAsync(dataToRead){
try {
await readVal();
const readAll = await connected();
console.log(readAll);
}catch(e){
console.log(e);
}
}
testAsync();
Unfortunately, I still obtain readAll = false, but should be = {'DB12,REAL140': 23:45}. Could you point me what is wrong?
Upvotes: 1
Views: 327
Reputation: 370799
The readAllItems
callback - called valuesReady
in your first code - accepts two parameters. The first is a possible error, and the second is the actual result:
conn.readAllItems(valuesReady);
// ...
function valuesReady(anythingBad, values) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
console.log(values); // return {'TEST5': 23.5}
doneReading = true;
if (doneWriting) { process.exit(); }
}
But in your second code, the first parameter is being used by the resolve
callback (and any subsequent arguments passed to resolve
get ignored). So, as is, you're ending up with a resolve value of the anythingBad
, which will be falsey under normal circumstances. That's why you're getting false
at the moment.
Try rejecting with the first (error) parameter if it exists, and resolving with the second (resolved values) parameter otherwise:
function connected() {
conn.addItemsNow(['DB12,REAL140']);
return new Promise((resolve, reject) => {
conn.readAllItems((anythingBad, values) => {
if (anythingBad) reject(anythingBad);
else resolve(values);
});
});
}
You should also have the readVal
reject in the case of an error (it will currently always resolve, which is probably not what you want):
function readVal(){
return new Promise((resolve, reject) => {
conn.initiateConnection({port: 102, host: '172.16.85.10', rack: 0, slot: 1}, (err) => {
if (err) reject(err);
else resolve();
});
})
}
You can also use util.promisify
to translate the callbacks to Promises automatically, but it looks a bit awkward since it's only operating on the conn
(and needs to preserve its calling context, while not changing the nodes7
prototype):
const { promisify } = require('util');
const initiateConnectionPromisified = promisify(conn.initiateConnection).bind(conn);
const readAllItemsPromisified = promisify(conn.readAllItems).bind(conn);
(async () => {
await initiateConnectionPromisified({port: 102, host: '192.168.0.2', rack: 0, slot: 1});
conn.setTranslationCB(function(tag) {return variables[tag];});
conn.addItems(['TEST5']);
await readAllItemsPromisified();
})();
Upvotes: 2