Home > Back-end >  How to make a return wait a timeout inside a function in typescript
How to make a return wait a timeout inside a function in typescript

Time:12-14

I'm trying to make a method that returns a promise, but i need to wait in a timeout to return the data of that promise. The thing is that the method returns the promise without the timeout has ended, so the data is incorrect. Do you know some way to make the return wait to the resolution of the timeout? Thanks :)

`

export default async function scrapper(city: string): Promise<Coords> {
    let latitude = "";
    let longitude = "";
    let driver = openDriver();
    setTimeout(async () => {
        await driver.findLatitude(city).then((value) => {
            latitude = value;
        }).then(async () => {
            await driver.findLongitude(city).then((value) => {
                longitude = value;
            });
        }).then(async () => {
            await driver.quit();
        });
    }, 1000);

    return new Promise(async (resolve) => { resolve({ lat: latitude, long: longitude }) })
}

`

01234567890123456789

CodePudding user response:

generally avoid new Promise. The only purpose for this, is to transform callback style code to Promises. Directly calling resolve(...) in sync never makes sense. For this there would be Promise.resolve(...).

Also an async function always automatically returns a Promise. So no need to create one yourself.

Now, one of the few use-cases of new Promise is actually setTimeout. A common trick is this:

const wait = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds))`;

this gives you a simple function that waits some time, that you can await like await wait(1000).

In the next step, its important to realize that these this:

await driver.findLatitude(city).then((value) => {
  latitude = value;
})

is 100% identical to this:

latitude = await driver.findLatitude(city);

Which means you can rewrite your code like this:

const wait = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds));

export default async function scrapper(city: string): Promise<Coords> {
  let latitude = "";
  let longitude = "";
  let driver = openDriver();
  await wait(1000);

  latitude = await driver.findLatitude(city)
  longitude = await driver.findLongitude(city);
  await driver.quit();

  return { lat: latitude, long: longitude };
}

Now a next step would be to remove the let, and replace them by const.

CodePudding user response:

First I will suggest couple of things.

For what you asked you need to wrap every thing in promise and resolve it in the setTimeout.

I will suggest you to use Promise.all() save tone of time when making multiply http requests.

(use this only if the call you making not depending on each other)

It should look like something like this:

  promiseExample() {

    return new Promise((resolve, reject) => {
      const promiseArray = [];
      const driver = openDriver();
      promiseArray.push(driver.findLatitude(city))
      promiseArray.push(driver.findLongitude(city))
      promiseArray.push(driver.quit()) // if this action not depend on the rest if it does put it inside the then

      Promise.all(promiseArray)
        .then((result) => {
          setTimeout(() => {
            resolve({ lat: result[0], long: result[1] });
          }, 1000) // use here what ever time you want 
        })
    })
  }

or in async way:


    export default async function scrapper(city: string) {
    let driver = openDriver();
    const promiseArray = []
    promiseArray.push(driver.findLatitude(city));
    promiseArray.push(driver.findLongitude(city));
    // if driver.quit() depened on other then if not the add it like the others 
    const result = await Promise.all(promiseArray);
    await driver.quit();
    setTimeout(() => {
       return { lat: result[0], long: result[1] }
    }, 1000);
}

Using promise all will speed up the API request and make you wait way less. because you fire them after the other and wait for all responses instead of fire request wait for response then fire next etc.

Moreover you should implement the reject(for promise) or use try catch(for async) if needed.

  • Related