Объединение нескольких запросов AJAX в один вывод - PullRequest
0 голосов
/ 09 мая 2018

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

NOT AN OFFICIAL TRANSLATION. FOR REFERENCE USE ONLY.
Field_Name: Translation
Field_Name2: Translation
Field_Name3: Translation

Исходя из опыта работы с питоном, с небольшим опытом работы с JavaScript, я нахожу это очень трудным. Код ниже заполнен на 85% -90%. Я успешно захватил имена полей и текст, вызов сделан для api перевода, и перевод возвращается. Моя проблема состоит в том, чтобы связать его как одно предупреждение, а не как отдельное предупреждение для каждого перевода. Из-за природы ajax я понимаю, что трудно работать с возвращенными данными вне асинхронного запроса. Я думаю, что я на правильном пути, вызывая другую функцию в запросе ajax, но мне интересно, есть ли лучший способ сделать это.

//Gathers all the field names and text associated with them.
$(document).ready(function() {

var allSpans = document.getElementsByTagName('span');
var spanlist = [];
var x = 0;
var ajax_data = [];
var fieldlabels = [];

[].slice.call(allSpans).forEach(function(span) {
    if(span.className === 'readonlyfield') {
        if(span.textContent) {
            var spanobject = {};
            var textfrom = 'en';
            var textto = 'it';
            var text = span.innerText;
            var parentelem = document.getElementById(span.parentNode.id);
            var parenttext = parentelem.innerText;
            fieldlabels.push(parenttext + ': ');
            spanobject.parentfield = span.parentNode.id;
            spanobject.parenttext = parenttext;
            spanobject.textfrom = textfrom;
            spanobject.textto = textto;
            spanobject.text = text;
            spanlist.push(spanobject);
            x++;
        }
    }
});
var translatebutton = document.createElement('button');
translatebutton.setAttribute("id", x);
translatebutton.innerText = 'Translate!';
document.body.appendChild(translatebutton);
var finaloutput = "FOR REFERENCE USAGE ONLY. NOT AN OFFICIAL TRANSLATION." + '\n';
// On button click translate all text gathered and alert the final output.
$("button").click(function(){
    var outputdata = [];
    for(var i = 0, len = spanlist.length; i < len ; i++){
      var textfrom = spanlist[i].textfrom;
      var textto = spanlist[i].textto;
      var text = spanlist[i].text;
      var urlservice = 'MYTRANSLATIONURL==&text='+text+'&textfrom='+textfrom+'&textto='+textto;
      jQuery.support.cors = true;

           $.ajax({
               url: urlservice,
               type: 'GET',
               contentType: "text/html",
               success: function (data) {
                 getsomedata(data);
               },
               error: function (x, y, z) {
                   alert(x + '\n' + y + '\n' + z);
               }
           });
      function getsomedata(data) {
        alert(data);

// The code below does not work, I was experimenting with an idea.
        // ajax_data.push(data + '\n');
      }
      // var temp = fieldlabels.concat(ajax_data);
      // temp.toString();
};
});
});

Благодаря Эндрю я смог решить эту проблему, следующий код - мое окончательное решение для всех, кто испытывает подобные трудности:

$(document).ready(function() {

var allSpans = document.getElementsByTagName('span');
var spanlist = [];
var x = 0;

[].slice.call(allSpans).forEach(function(span) {
    if(span.className === 'readonlyfield') {
        if(span.textContent) {
            var spanobject = {};
            var textfrom = 'en';
            var textto = 'it';
            var text = span.innerText;
            var parentelem = span.parentNode.id;
            //REGEX to find field captions in my particular system.
            var captionID = parentelem.replace(/((TD))?/, "TDCAP");
            var captionelem = document.getElementById(captionID);
            var caption = captionelem.innerText;
            spanobject.spanparent = span.parentNode.id;
            spanobject.captionfield = captionelem;
            spanobject.caption = caption;
            spanobject.textfrom = textfrom;
            spanobject.textto = textto;
            spanobject.text = text;
            spanlist.push(spanobject);
            x++;
        }
     }
});

var translatebutton = document.createElement('button');
translatebutton.setAttribute("id", x);
translatebutton.innerText = 'Translate!';
document.body.appendChild(translatebutton);
var finaloutput = "FOR REFERENCE USAGE ONLY. NOT AN OFFICIAL TRANSLATION." + '\n';
$("button").click(function(){
    var outputdata = [];
    var completedRequests = 0;
    for(var i = 0, len = spanlist.length; i < len ; i++){
      var textfrom = spanlist[i].textfrom;
      var textto = spanlist[i].textto;
      var text = spanlist[i].text;
      let parentLet = spanlist[i].spanparent;
      let textLet = spanlist[i].text;
      let captionfield = spanlist[i].captionfield;
      let caption = spanlist[i].caption;
      var urlservice = 'MYTRANSLATIONURL==&text='+text+'&textfrom='+textfrom+'&textto='+textto;
      jQuery.support.cors = true;
           $.ajax({
               url: urlservice,
               type: 'GET',
               contentType: "text/html",
               success: function (data) {
                 datastring = caption + ": " + data;
                 outputdata.push(datastring);
               },
               error: function (x, y, z) {
                   alert(x + '\n' + y + '\n' + z);
               },
               complete: function() {
                 if (++completedRequests >= len) {
                   getsomedata(outputdata);
                 }
               }
           });
      function getsomedata(data) {
        var finaldata = data.join("\n\n");
        final = finaloutput + '\n' + finaldata;
        alert(final);
      }
};
});
});

1 Ответ

0 голосов
/ 09 мая 2018

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

После успешного завершения запросов вы можете добавить данные к объекту или массиву, и это будет показано в конце.

Основная часть, на которую нужно смотреть ниже -

if (++completedRequests >= len) {
  getsomedata(outputdata)
}

completedRequests увеличивается каждый раз, когда ajax-запрос завершается (успех или неудача). Когда эта сумма равна длине цикла, мы знаем, что мы закончили и можем показать наши данные.

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

var spanlist = [0, 0, 0, 0]; // example placeholder

$("button").click(function() {
  var outputdata = [];
  var completedRequests = 0;
  for (var i = 0, len = spanlist.length; i < len; i++) {
    var noLet = i;
    let yesLet = i;
    $.ajax({
      url: "https://jsonplaceholder.typicode.com/posts/" + (i + 1),
      type: 'GET',
      success: function(data) {
        outputdata.push(data.id);
        // These console logs are to explain how let is used with this ajax inside a loop
        console.log("noLet: " + noLet);
        console.log("yesLet: " + yesLet);
      },
      error: function(xhr, status, errorThrown) {
        console.error(status + '\n' + JSON.stringify(xhr) + '\n' + errorThrown);
      },
      complete: function() {
        if (++completedRequests >= len) {
          getsomedata(outputdata)
        }
      }
    });
  }
});

function getsomedata(data) {
  alert(data);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click Me</button>

Редактировать: я добавил, как использование let может помочь вам использовать переменные, которые определены вне обработчика успеха ajax, но используются внутри обработчика успеха. Если вы видите, что noLet печатает 3 всегда, потому что var является областью действия функции, и к тому времени, когда последний запрос возвращается, переменная i уже прошла через цикл и является последним значением.

, поскольку let является областью действия блока (цикл for в этом примере), он будет содержать значение i, которое использовалось при запуске функции ajax в той же итерации цикла. Вот хорошая нить о разнице между var и let

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...