nodejs обещает лучший способ реализации из settimeout

У меня есть следующие функции, работающие в nodejs, но я использую setTimeout, а не обещание. Если createchange занимает больше времени, чем у меня есть тайм-аут, мой код дает сбой, но не правильно перехватывает ошибку.

Как мне заменить или изменить следующие функции для работы с обещанием, поэтому deploychange ожидает завершения createchange, прежде чем продолжить выполнение кода?

Я пробовал пару вещей, но ничего не работает. Не уверен, какую функцию я должен переделать для наиболее эффективного решения.

Любая помощь будет оценена по достоинству.

Первая функция

function createchange(accessToken){
        const data = {
            templateName: "Template 1",
            summary: "Deploy  Change",

            configurationItems: [
              config_item
            ],
            wasEnvUsedForTesting: false,
            environment: test_env
          };

        rp({
            url: dbConfig.cmas_url,
            resolveWithFullResponse: true,
            method: 'POST',
            json: true,
            auth: {
            bearer: accessToken
            },
            body: data,
            headers: {
            'Content-Type': 'application/json',
            'apikey': dbConfig.consumer_key,
            },
        }, function(err, res) {
            if(err){
                console.log(err.body);
            }else{
                console.log(res.body);
                crq = res.body.changeid;
            }

        });
    }

2-я функция

  function run() {
           deploychange();
          setTimeout(function(){ deployinsert(); }, 7500);
           deployrun();
      }

3-я функция

        function deploychange (callback) {
        if (req.body.deployEnv == "PRD"){
          getToken(function(accessToken) {
          createchange(accessToken);   
          })}; 

        } 

person Spring_Reboot    schedule 12.12.2019    source источник


Ответы (1)


Согласно документации request-promise, rp возвращает обещание.

На самом деле вы можете преобразовать свою функцию createChange, чтобы она возвращала обещание следующим образом:

const createchange = accessToken => {
    const data = {
        templateName: 'Template 1',
        summary: 'Deploy  Change',

        configurationItems: [config_item],
        wasEnvUsedForTesting: false,
        environment: test_env
    };

    return rp({
        url: dbConfig.cmas_url,
        resolveWithFullResponse: true,
        method: 'POST',
        json: true,
        auth: {
            bearer: accessToken
        },
        body: data,
        headers: {
            'Content-Type': 'application/json',
            apikey: dbConfig.consumer_key
        }
    });
};

Затем вы можете вызвать свою функцию с помощью ключевого слова await.

await createchange(accessToken);

Убедитесь, что функция, использующая ожидание, помечена как асинхронная.

Вы также можете написать это так:

createchange(accessToken)
    .then(({changeId}) => {
        // Do someth with the changeId
    })
    .catch(/* Error handling */)
person Bastien G    schedule 12.12.2019
comment
Я собираюсь дать Бастьену шанс с помощью асинхронности. Могу ли я по-прежнему вызывать свой changeId с помощью data.body.changeId? - person Spring_Reboot; 12.12.2019
comment
Конечно, функция createChange вернет часть res классической функции обратного вызова. Часть err будет брошена/захвачена. Таким образом, вы можете в основном сделать: const res = await createchange(accessToken); и получить доступ к res.body.changeid - person Bastien G; 13.12.2019
comment
@Spring_Reboot, вам нужна дополнительная информация для решения вашей проблемы. Таким образом, deploychange() должен возвращать Promise, а для этого getToken() должен быть промисифицирован. Возврат Promise от createChange() — это только часть решения. - person Roamer-1888; 19.12.2019