Проблемы с асинхронностью при использовании JavaScript для вызовов API и записи данных в файл - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь получить данные из Hubspot и записать JSON, который он возвращает в файл.Я специально использую этот пакет https://www.npmjs.com/package/hubspot, потому что он имеет встроенный отказоустойчивый для ограничений скорости Hubspot.

К сожалению, в последнее время я не так много кодировал, и столкнулся с проблемой асинхронности моего кода.Было бы замечательно, если бы кто-то мог сказать мне, что я делаю здесь неправильно, потому что мне действительно нужно, чтобы этот скрипт работал.

Мой код:

const Hubspot = require('hubspot');
const fs = require('fs');
const hubspot = new Hubspot({ apiKey: 'apiKey' });

let engage = [];

const vid = [
'dummyId', 'dummyId2', 'dummyId3' 
];

function createFile () {
    fs.writeFile('./Engagements.json', engage, (err) => {
        if (err) {
            console.log(err);
            return;
        }
        console.log('Success!');
    });
}

(function () {
    for (i = 0; i <= vid.length; i++) {
        hubspot.engagements.getAssociated(hubspot.contacts, vid.i)
            .then(results => {engage.push(results)});
    }
    setTimeout(createFile, 10000);
})();

И вот сообщение об ошибке Iполучаю: (node:37315) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 53)

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Вот правильная реализация .catch.Вы все равно должны реализовать предложение @KevinB, которое он сделал в комментариях после того, как вы найдете и исправите ошибку.

(function() {
  for (i = 0; i <= vid.length; i++) {
    hubspot.engagements.getAssociated(hubspot.contacts, vid[i])
      .then(results => {
        engage.push(results);
      })
      .catch(err => console.log(err));
  }
  setTimeout(createFile, 10000);
})();
0 голосов
/ 18 декабря 2018

Разве вы не должны ждать, пока не вернутся все обещания?Вместо того, чтобы зависеть от setTimeout, вам лучше подождать всех обещаний (ищите Promise.all).Вы также можете взглянуть на статью (https://davidwalsh.name/promises-results)

Promise.all(promises.map(p => p.catch(() => undefined)));

В вашем случае это будет что-то вроде

(function () {
    var promises = [];
    for (i = 0; i <= vid.length; i++) {
        promises.push(hubspot.engagements.getAssociated(hubspot.contacts, vid.i));
    }
    Promise.all(promises.map(p => p.catch(e => e))).then(results => {
        results.forEach(result => {
            if (!(result instanceof Error)) {
                engage.push(result);
            }
        });
        createFile();
    });
})();
0 голосов
/ 18 декабря 2018

Немного сложно отладить из фрагмента, но из сообщения об ошибке вы можете попробовать это:

(function() {
  for (i = 0; i <= vid.length; i++) {
    hubspot.engagements.getAssociated(hubspot.contacts, vid.i).then(results => {
      engage.push(results)
    }).catch(err => console.log(err))
  }
  setTimeout(createFile, 10000);
})();

По сути, вам нужен перехват, чтобы мы не получили необработанное отклонение обещания ...Это может не решить все это, но это шаг в правильном направлении ...

...