Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 03.02.2022, 18:01
Новичок на форуме
Отправить личное сообщение для mazhaka Посмотреть профиль Найти все сообщения от mazhaka
 
Регистрация: 01.12.2020
Сообщений: 4

Помогите правильно отправить запросы на сервер.
Есть такой код , написан не мной он занимается тем что отправляет на sendgrid.com/dynamic-templates шаблоны станиц , проблема заключается в том что раньше было. 2 языка английский и немецкий и мы добавили еще 9 языков . и когда происходит deploy сервер от sendgrid принимает где то 100 запросов а потом отправляет ошибку Error: getaddrinfo ENOTFOUND api.sendgrid.com api.sendgrid.com:443 , если отправлять опять маленькое количество шаблонов например опять 2 языка , то ошибки нету , я пришел к такому выводу , что этот код отправляет моментально много запросов , а sendgrid просто видит что ему пытаются отправить очень много запросов за один раз и просто возвращает ошибку . Проблема в том что с таким я не работал , и я не знаю как мне сделать промежуточные паузы между запросами , например если выгружены все шаблоны он будет их обновлять updateTemplateVersion() и если их там 200 а сервер после 100 отправит ошибку , как мне в async/await сделать промежуточную паузу хотя бы между каждым запросов или через например каждые 50 на несколько секунд . если вы взгляните на код и сможете мне помочь буду очень благодарен !!!!





const api = axios.create({
  baseURL: "https://api.sendgrid.com/v3/",
  headers: {
    "Authorization": "Bearer " + token,
  },
});

// Loads the subjects from the given json translation file that looks like
//    {
//      "some-name-subject": "foo",
//      "something-else": "bar",
//      ...
//    }
// and returns the subjects in the form
//    {
//      "some-name": "foo",
//      ...
//    }
// without the "-subject" suffix and without non-subject translation keys.
async function loadSubjectsFromFile(path) {
  // parse translation file
  let translations = JSON.parse(fs.readFileSync(path))

  // find subject translation keys
  var onlySubjects = {};
  for (const key in translations) {
    if (!translations.hasOwnProperty(key)) continue;

    // check for "-subject" suffix
    const match = key.match(/^([-_a-zA-Z0-9]+)-subject$/);
    if (match === null) continue;

    // use name without the "-subject" suffix
    onlySubjects[match[1]] = translations[key];
  }

  return onlySubjects;
}

// Loads all subjects from the translation files in the ./lang directory and
// returns them by language in the form
//    {
//      "en": {
//        "some-name": "some-name subject translation string",
//        ...
//      },
//      ...
//    }
// .
async function loadAllSubjects() {
  // find translation files
  let files = await glob("./lang/*/index.json");

  // extract language from filename
  files = files.map(path => path.match(/\/([a-z]{2})\/index\.json$/))
    .filter(match => match !== null)
    .map(({ 1: language, input: path }) => ({ language, path }));

  // load subjects from file
  const addSubjects = file => loadSubjectsFromFile(file.path)
    .then(subjects => ({ ...file, subjects }));
  files = await Promise.all(files.map(addSubjects));

  // transform output
  return files.reduce((prev, file) => ({ ...prev, [file.language]: file.subjects }), {});
}

// Loads all templates from the ./dist directory and returns them in the form
//    [
//      {
//        "project": "some-project",
//        "name": "some-name",
//        "language": "en",
//        "content": "...",
//      },
//      ...
//    ]
// .
async function loadAllTemplates() {
  // find template files
  let files = await glob("./dist/*/*.html");

  // extract project, name and language from filename
  files = files.map(path => path.match(/\/([-_a-zA-Z0-9]+)\/([-_a-zA-Z0-9]+)-([a-z]{2})\.html$/))
    .filter(match => match !== null)
    .map(({ 1: project, 2: name, 3: language, input: path }) => ({ project, name, language, path }));

  // load files
  const addContent = file => fs.promises.readFile(file.path)
    .then(content => ({ ...file, content: content.toString() }));
  files = await Promise.all(files.map(addContent));

  // replace placeholders
  files = files.map(f => ({...f, content: f.content
    .replace("PACE_ID_LOGO_DARK", paceIdLogoDarkUrl)
    .replace("PACE_PAY_LOGO_DARK", pacePayLogoDarkUrl)
    .replace("COFU_LOGO_DARK", cofuLogoDarkUrl)
    .replace("PACE_ID_LOGO", paceIdLogoUrl)
    .replace("PACE_PAY_LOGO", pacePayLogoUrl)
    .replace("COFU_LOGO", cofuLogoUrl)
    .replace(/FEEDBACK_BULLET/g, bulletIconUrl)
    .replace(/MADE_WITH_LOVE_DARK/g, madeWithLoveDarkUrl)
    .replace(/MADE_WITH_LOVE/g, madeWithLoveUrl)
    .replace(/SIGN_PHIL_DARK/g, signPhilDark)
    .replace(/SIGN_PHIL/g, signPhil)
    .replace(/PHIL_PICTURE/g, picturePhil)
  }));

  // transform output
  return files.map(({ project, name, language, content }) => ({ project, name, language, content }));
}

// Loads all templates from the ./dist directory and subjects from the ./lang
// directory and returns them in the form
//    [
//      {
//        "name": "some-project.en.some-name",
//        "content": "...",
//        "subject": "some-name subject translation string",
//      },
//      ...
//    ]
// .
async function loadTemplatesWithSubjects() {
  const subjects = await loadAllSubjects();
  const templates = await loadAllTemplates();

  const mustFindSubject = (language, name) => {
    const subject = subjects[language][name];
    if (!subject) throw `no subject found for "*.${language}.${name}"`;
    return subject
  }

  // combine templates and subjects
  return templates.map(({ project, name, language, content }) => ({
    name: `${project}.${language}.${name}`,
    content,
    subject: mustFindSubject(language, name),
  }))
}

// Loads all templates from remote and returns them in the form
//    [
//      {
//        "name": "some-project.en.some-name",
//        "id": "d-ebe8ecc4afc6413f9c24bef2abfca73b",
//        "version": "8ab2d9bd-d60b-40b9-8228-e9042e6820a1",
//      },
//      ...
//    ]
// .
async function loadRemoteTemplates() {
  const response = await api.get("/templates?page_size=100&generations=dynamic");

  // filter templates by name "some-project.language.some-name"
  const templates = response.data.result.filter(t => t.name.match(/^[-_a-zA-Z0-9]+\.[a-z]{2}\.[-_a-zA-Z0-9]+$/) !== null);

  // transform output
  return templates.map(({ id, name, versions }) => ({
    name,
    id,
    version: (v => v ? v.id : undefined)(versions.find(v => v.active)),
  }))
}

// Loads all templates from the filesystem and remote and returns them in the
// form
//    [
//      {
//        "name": "some-project.en.some-name",
//        "content": "...",
//        "subject": "some-name subject translation string",
//        "id": "d-ebe8ecc4afc6413f9c24bef2abfca73b",
//        "version": "8ab2d9bd-d60b-40b9-8228-e9042e6820a1",
//      },
//      ...
//    ]
// . Note that per template most properties can be undefined. At minimum a
// template has the "name" and either the "content" or "id" property given.
async function matchLocalAndRemoteTemplates() {
  const local = await loadTemplatesWithSubjects();
  const remote = await loadRemoteTemplates();

  // combine local and remote
  return local.concat(remote).reduce((prev, template) => {
    const existing = prev.find(t => t.name === template.name);
    return existing
      ? [ // consolidate
        ...prev.filter(t => t.name !== existing.name),
        { ...existing, ...template },
      ]
      : [...prev, template]; // add
  }, []);
}

async function updateTemplateVersion(template) {
  console.log("updating template version", template.name)
  
  const resp = await api.patch(`/templates/${template.id}/versions/${template.version}`, {
    active: 1,
    subject: template.subject,
    html_content: template.content,
    name: versionName,
  })

  if (resp.status !== 200) throw `failed to update template ${template.name}: ${resp.status}: ${resp.data}`;

  return template;
}

async function createTemplate(template) {
  console.log("creating template", template.name)

  const resp = await api.post(`/templates`, {
    name: template.name,
    generation: "dynamic",
  })

  if (resp.status !== 201) throw `failed to create template ${template.name}: ${resp.status}: ${resp.data}`;

  template.id = resp.data.id
  return template;
}

async function createTemplateVersion(template) {
  console.log("creating template version", template.name)
  
  const resp = await api.post(`/templates/${template.id}/versions`, {
    active: 1,
    subject: template.subject,
    html_content: template.content,
    name: versionName,
  })

  if (resp.status !== 201) throw `failed to create template version ${template.name}: ${resp.status}: ${resp.data}`;

  template.version = resp.data.id
  return template;
}


// update remote
matchLocalAndRemoteTemplates()
  // safeguard: ignore all templates of projects we don't know
  .then(templates => templates.map(t => ({...t, project: t.name.split('.')[0]})))
  .then(templates => templates.filter(t => supportedProjects.includes(t.project)))
  // update template versions that exist remotely and locally
  .then(templates => Promise.all(templates.map(t => t.version && t.content ? updateTemplateVersion(t) : t)))
  // create templates that don't exist remotely, but locally
  .then(templates => Promise.all(templates.map(t => !t.id && t.content ? createTemplate(t) : t)))
  // create template versions that don't exist remotely, but locally
  .then(templates => Promise.all(templates.map(t => !t.version && t.content ? createTemplateVersion(t) : t)))
  // delete templates that exist remotely, but not locally (disabled because of partner-mails)
  //.then(templates => Promise.all(templates.map(t => t.id && !t.content ? deleteTemplate(t) : t)))
  // report all errors
  .catch(err => {
    console.error(err);
    process.exit(1);
  });
Ответить с цитированием
  #2 (permalink)  
Старый 03.02.2022, 18:19
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,590

Ленивый вариант без переписывания всего подряд - добавить либу типа axios-concurrency.
__________________
29375, 35
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите отправить json на сервер evgeniy123 jQuery 9 08.06.2013 08:35
Помогите пожалуйста правильно написать скрипт raffx Events/DOM/Window 17 16.10.2012 20:31
Ребята помогите правильно реализовать цепочки функций как в jquery mrgordon Общие вопросы Javascript 6 04.06.2012 20:40
Помогите правильно написать регулярное выражение fredrsf Общие вопросы Javascript 4 14.02.2012 14:30
(jScrollPane) помогите правильно прописать css для div'ов _shpion_ jQuery 0 14.05.2011 17:16