简体   繁体   中英

getting a callback to finish before continuing a loop?

so I have been stuck on this for a while. If someone could help me out with this i would really appreciate it! What i want is to have my function and its callback finish before continuing on in a loop. I call "translate_all" after a user has input a text in english in a textarea and has clicked the translate button. ("Method", "g_loop", "g_where" and "go" are global variables.) Ultimately what i want is to have the input english phrase translate to the next language in the array, then have that translated back to english to see if there is a difference, and then continue on through all the languages.

I tried promises but honestly i couldnt wrap my head around it. I tried this "hackish" approach with trapping the loop in a while loop until the global variable "go" is changed following the callback. But, what happens is that the browser freezes when i run this and i think it is because although the approach stops the loop from continuing, it is so stuck in the loop that it never receives the message from the callback that "go" was changed. Perhaps I could do some sort of event listener as was quickly recommended to me, but im not sure. I feel that i am so close, and it is driving me mad trying to get this to work for so long. Any and all help is appreciated! Thanks!

I have this:

var translate_all = function translate_all () {
  // set global g_where to this div to append an image
  g_where = $("#g_div");
  g_where.append("<img alt='Google Logo' src='/img/google_g_medium.png'/><br>");
  // get the text the user input
  var a_text = $("#accuracy_text").val();  
  // translation codes for api
  var language_codes = ["en", "ar", "bg", "ca", "hr", "cs", "da", "nl", "et", "fi", "fr", "de", "el", "ht", "id", "it", "ko", "lv", "lt", "ms", "mt", "no", "fa", "pl", "pt", "ro", "ru", "sl", "sl", "es", "th", "tr", "uk", "ur", "vi"]; 
  // set global g_loop to what text the user input
  g_loop = a_text;
  // start a loop
  for (var i = 1; i < language_codes.length; i++)
  {
    // error checking and trying to debug and see what is wrong
    console.log("working")
    // define which callback i want to run
    method = 2;
    // this callback sets the response from google placed in g_response to g_loop; it translates from one language in loop to the next
    GoogleTranslate(g_loop, language_codes[i-1], language_codes[i]);
    console.log("continue");
    // THIS is where i try to get the loop to stop until the callback has run because this loop is only able to break when the callback has finished
    while (go == 0)
    {
      if (go == 1)
      {
        break;
      }
    }
    // set go back to zero
    go = 0;
    // set g_where and append the response to the div
    g_where = $("#g_div");
    g_where.append(g_response)
    method = 1;
    // this translates the initial response back to english to see if there is a difference and appends it to the div
    GoogleTranslate(g_loop, language_codes[i], "en");
    // trying to make sure the callback is executed again before continuing
    while (go == 0)
    {
      if (go == 1)
      {
        break;
      }
    }
    go = 0;
  }
}


function GoogleTranslate (text, from, to) {

  var newScript = document.createElement('script');
  var sourceText = escape(text);
  newScript.type = 'text/javascript';
  var APIKEY = 'my api key';
  var source = 'https://www.googleapis.com/language/translate/v2?';
  source += 'key=' + APIKEY;
  source += '&source=' + from;
  source += '&target=' + to;
  source += '&callback=google_translation';
  source += '&q=' + sourceText;
  newScript.src = source;
  console.log("sent");

  // send the reuqest to google api
  $('head')[0].appendChild(newScript); 
}


// callback
function google_translation(response) {
  g_response = response.data.translations[0].translatedText;
  if (method == 0)
  {
    // replaces text in a given location (not for code shown)
    g_where.val(g_response);
    console.log("0");
  }
  if (method == 1)
  {
    // appends text in a given location
    g_where.append(": " + g_response + "<br>");
    console.log("1");
  }
  if (method == 2)
  {
    // sets variable to response
    g_loop = g_response;
    console.log("2");
  }
  go = 1;
  console.log("translated");      
}

You can create a chain of promises that will run in sequence like this:

myList.reduce((promise, item) => {
  return promise.then(() => new Promise((resolve, reject) => {
    // do whatever you need to do here
    // resolve when finished with this iteration.
  }))
}, Promise.resolve());

So imagine you had a list like [1,2,3] and you gave the callback promise. Using this method more or less translates to this:

Promise.resolve()
  .then(1 => function () { })
  .then(2 => function () { })
  .then(3 => function () { });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM