Search code examples
javascriptasynchronousasync-awaitpromisereturn

JS Promise function call that returns object


I have a async fetch function that waits 2 seconds and returns a object:

async function fetch() {
    var object;
    await setTimeout(() => { object = { name: 'User', data: 'API Data' } }, 2000);
    return object;
}

I want to display the object when the initialization is completely done (after 2 seconds)

fetch().then((val) => {
    console.log("DONE!"); 
    console.log(val.name);
}).catch((err) => {
    console.log("ERROR!");
    console.log(err);
});

The code prints both DONE and ERROR Cannot read properties of undefined (reading 'name')

I have tried with Promise, no luck

let promise = new Promise((resolve, reject) => {
    let request = fetch();
    if (request !== undefined)
        resolve(request);
    else
    reject(request);

}).then((val) => {
    console.log(val);
});

How can I properly check that fetch() has returned a value before printing without changing the inside of the function. I can delete the async and await in it but I am unable to edit it (I.E. adding a Promise inside)


Solution

  • Based on requirement

    I can delete the async and await in it (fetch function) but I am unable to edit it (I.E. adding a Promise inside)

    The only way I see is to override window.setTimeout function to make it to return a promise. That way you will be able to await it and there will be no need to modify your fetch function.

    const oldTimeout = window.setTimeout;
    window.setTimeout = (fn, ms) => {
      return new Promise((resolve, reject) => {
        oldTimeout(() => {
          fn();
          resolve();
        }, ms);
      });
    };
    
    async function fetch() {
      var object;
      await setTimeout(() => {
        object = { name: "User", data: "API Data" };
      }, 2000);
      return object;
    }
    
    fetch()
      .then((val) => {
        console.log("DONE!");
        console.log(val.name);
      })
      .catch((err) => {
        console.log("ERROR!");
        console.log(err);
      });

    NOTE: For anyone without this requirement - please, use other answers to this question or check await setTimeout is not synchronously waiting for additional details/explanations. This kind of overridings are very confusing due to everyone expect common and well-known functions to behavior in a way described in the docs.