Обратный звонок к обещаниям (node7) - PullRequest
1 голос
/ 04 февраля 2020

Я пытаюсь преобразовать функции обратного вызова из API-интерфейса nodeS7 в обещания. Есть код с обратным вызовом, который работает правильно:

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(); }
}

Теперь я пытаюсь сделать что-то подобное:

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();

К сожалению, я все еще получаю readAll = false, но должен be = {'DB12, REAL140': 23:45}. Не могли бы вы указать мне, что не так?

1 Ответ

2 голосов
/ 04 февраля 2020

Обратный вызов readAllItems, называемый valuesReady в вашем первом коде, принимает два параметра. Первый - это возможная ошибка, а второй - фактический результат:

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(); }
}

Но во втором коде первый параметр используется обратным вызовом resolve (а все последующие аргументы передаются resolve игнорируется). Таким образом, в результате вы получите значение разрешения anythingBad, которое при нормальных обстоятельствах будет ложным. Вот почему вы получаете false в данный момент.

Попробуйте отклонить первый параметр (ошибка), если он существует, и разрешить вторым параметром (разрешенные значения) в противном случае:

function connected() {
    conn.addItemsNow(['DB12,REAL140']);
    return new Promise((resolve, reject) => {
        conn.readAllItems((anythingBad, values) => {
            if (anythingBad) reject(anythingBad);
            else resolve(values);
        });
   });
}

Вы также должны иметь отклонение readVal в случае ошибки (в настоящее время она всегда разрешается, что, вероятно, не то, что вам нужно):

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();
         });
    })    
}

Вы также можете использовать util.promisify чтобы автоматически перевести обратные вызовы в Promises, но это выглядит bit неловко, так как он работает только на conn (и должен сохранять свой контекст вызова, не изменяя прототип nodes7):

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();
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...