0

I'm trying to translate all elements of the array wordList and pushing them to a new list translatedWordList, but because translate() is async the new list is empty when I callback or return it

function translateWordList(wordList, callback) {
  var translatedWordList = [];

  wordList.forEach((word) => {
    translate(word, (translation) => {
      translatedWordList.push(translation);
    });
  });

  callback(translatedWordList);
}

I tried to solve this by delaying the callback using a while loop that runs until the length of translatedWordList and wordList match, but the function translate is not logging anything

function translateWordList(wordList, callback) {
  var translatedWordList = [];

  wordList.forEach((word) => {
    translate(word, (translation) => {
      translatedWordList.push(translation);
      console.log(translation)
      counter++;
    });
  });

  while (translateWordList.length < wordList.length) {}
  callback(translatedWordList);
}

1 Answer 1

1

Instead of using a Array#forEach, just use a normal for loop and make your function async so you can use the await keyword.

async function translateWordList(wordList, callback) {
  var translatedWordList = [];
  
  for(const word of wordList) {
    translatedWordList.push(await translate(word));
  }

  callback(translatedWordList);
}

If your translate function does not return a promise and only uses a callback, then you can promisify that function.

function translatePromise(word) {
  return new Promise((resolve, reject) => {
    translate(word, (translation, err) => {
      // assuming your callback signals an error in the second parameter
      if(err) {
        reject(err);
        return;
      }
      resolve(translation);
    });
  });
}

Then replace the translate(word) call in the first example with translatePromise(word).

However, if you don't want to work with async/await you could do something like this.

function translateWordList(wordList, callback) {
  Promise.all(wordList.map((word) => {
    return new Promise((resolve) => {
      translate(word, resolve);
    });
  }))
  .then(callback);
}
Sign up to request clarification or add additional context in comments.

5 Comments

the problem is that translate() takes a lot of time to execute so I need it as an async function is there any faster alternatives than promises?
@Joonius did you try the last option? It'll run all your promises at the same time with "Promise.all"?
And in general, if your method is asynchronous then unfortunately you're limitted to the speed of which it takes to resolve. The fastest you can go is to run all your promises at the same time.
Is it possible to run all the promises at the same time? If so, how do I do it?
@Joonius the last example runs all your promises at the same time with Promise.all. You can read more about it here. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.