Сообщение отправляется до завершения обеих функций

Я использую модуль pubchem-access для бота Node.JS, чтобы получить определенные химические свойства соединения и затем отправить их в Telegram. Я хочу объединить несколько свойств и получить идентификатор CAS, но получение идентификатора CAS - это отдельная функция (см.: http://mmmalik.github.io/pubchem-access/). Я попытался объединить оба в одно сообщение, просто поместив нужные функции друг за другом:

            case 'prop':
            var cas = ""
            pubchem
                .setName(commandText)
                .getCas()
                .execute(function(data, status) {
                    if (status != 1) {
                        cas = status;
                    } else {
                        cas = data
                    }
                });


            pubchem

                .setName(commandText)
                .getProperties(["IUPACName", "MolecularWeight", "MolecularFormula",
                    "CanonicalSMILES"
                ])
                .execute(function(data) {
                    msg.answer(
                        "IUPAC name: " + data.IUPACName + ",\nCAS :" + cas +
                        ",\nMW: " + data.MolecularWeight.toFixed(2) + ",\nFormula: " + data.MolecularFormula +
                        ", \nSMILES: " + data.CanonicalSMILES);
                });

            break;

Что я получаю при этом, так это то, что иногда свойство CAS еще не найдено, в то время как другие имеют, поэтому иногда сообщение get отправляется без CAS.

Что я могу сделать, чтобы гарантировать отправку сообщения только после того, как все требуемые свойства будут получены?

Извините, у меня проблемы с компоновкой кода

1 ответ

Решение

Вы можете заключить второй запрос в функцию и вызвать его, когда функция обратного вызова execute называется

pubchem
.setName(commandText)
.getCas()
.execute(function(data, status) {
    var cas = !Object.is(status,1) ? status : data;
    doSecondRequest(cas);
});

function doSecondRequest(cas){
    pubchem
    .setName(commandText)
    .getProperties(["IUPACName", "MolecularWeight", "MolecularFormula","CanonicalSMILES"])
    .execute(function(data) {
        msg.answer(
            "IUPAC name: " + data.IUPACName + ",\nCAS :" + cas +
            ",\nMW: " + data.MolecularWeight.toFixed(2) + ",\nFormula: " + data.MolecularFormula +
            ", \nSMILES: " + data.CanonicalSMILES);
        });
}

Или использовать promises обрабатывать асинхронные вызовы

var promise = new Promise((resolve) => {
    pubchem
    .setName(commandText)
    .getCas()
    .execute((data, status) => {
        var cas = !Object.is(status,1) ? status : data;
        resolve(cas);
    });
};

promise.then((cas) => {
    pubchem
    .setName(commandText)
    .getProperties(["IUPACName", "MolecularWeight", "MolecularFormula","CanonicalSMILES"])
    .execute((data) => {
        msg.answer(
            "IUPAC name: " + data.IUPACName + ",\nCAS :" + cas +
            ",\nMW: " + data.MolecularWeight.toFixed(2) + ",\nFormula: " + data.MolecularFormula +
            ", \nSMILES: " + data.CanonicalSMILES);
     });
});
Другие вопросы по тегам