admin管理员组

文章数量:1023648

If we have this function

const getData = () => {
  foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     return error;
   });
};

Although getData is not a promise itself, but it contains a promise, which is asyncrnous.

So what is the best way to wait for getData to return something. Async / Await doesn't work cause they work with promises.

Thanks.

If we have this function

const getData = () => {
  foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     return error;
   });
};

Although getData is not a promise itself, but it contains a promise, which is asyncrnous.

So what is the best way to wait for getData to return something. Async / Await doesn't work cause they work with promises.

Thanks.

Share Improve this question edited Dec 30, 2021 at 2:45 Soroush Bgm asked Dec 28, 2021 at 12:58 Soroush BgmSoroush Bgm 5424 silver badges18 bronze badges 4
  • 4 Add return before foo: return foo().then(...).catch(...) and call getData as getData().then(...) or await getData() – Yousaf Commented Dec 28, 2021 at 12:59
  • 2 To build up on @Yousaf's ment, currently getData() doesn't return anything. You need to make it return a Promise, so you can await it or chain .then() to it. – Jeremy Thille Commented Dec 28, 2021 at 13:01
  • 3 Note: Instead of returning error from the callback function of catch, throw it; returning an error or any value other than a rejected promise will fulfill the promise returned by getData() function which may or may not what you want. Alternatively, you could write getData() function as one liner: const getData => foo() and add the catch block in the code that calls the getData function. – Yousaf Commented Dec 28, 2021 at 13:04
  • As I understand the problem is about getting the result returned without wrapping it in a Promise. There are two ways. One is providing a callback that accepts the result: ``` const getData = (cb) => { foo() .then(result => { cb(result); return result; }) .catch(error => { return error; }); }; ``` And also you can use some blocking code that idles while the result is waiting for the assignment, but this is very bad practice I suspect. – arturasmckwcz Commented Dec 28, 2021 at 13:18
Add a ment  | 

3 Answers 3

Reset to default 3

Currently, getData() doesn't return anything. You need to make it return a Promise, so you can await it or chain .then() to it.

const getData = () => {
  return foo() // <-- here
  .then(result => {
     return result;
   })
  .catch(error => {
     throw error;
   });
};

// Now you can do :
getData().then(...)
// or :
const data = await getData();

In this case, you can also omit the curly braces and the explicit return, and make it implicit :

const getData = () => foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     throw error;
   });

Hey but what's that :

.then(result => {
         return result;
})

This does nothing. It takes a value and simply returns it without doing anything. You can remove it.

You can now rewrite getData() this way :

const getData = async () => {
    try {
      return await foo()
    } catch (error) {
      throw error;
    }
}

For that matter, this :

.catch(error => { throw error; });

or this :

catch (error) { throw error; }

are also pretty useless, they just "relay" (bubble up) the error that has to be caught in the calling function.

Now it's obvious getData does pretty much only one thing, it's returning foo(), which is a Promise. It's only a wrapper around a Promise... so it's actually pretty useless.

Bottom line, detData() is useless altogether. foo is a Promise; writing a function that returns a Promise so you can use it like a Promise is just... a Promise with an extra step. Just use foo directly.

let result;
try {
  result = await foo();
} catch (error) {
  console.log(error);
}
console.log(result);

This will not work because getData is not returning a value. You can add a return statement before foo call and wait for the return value.

const getData = () => {
  return foo();
};

getData().then(data => {
  console.log(data);
}).catch(err => {
  console.log(err);
});

To wait for an operation you must return a Promise or use a callback. The code snippet below runs and should illustrate how this works. I implemented a sample foo function that is actually asynchronous (wait for 1 second before returning the data '12345'). I used async/await to illustrate how that can work, but you can equally return the result of foo and use then instead.

const foo = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('12345'), 1000);
  });
}
const getData = async () => {
  const data = await foo();
  console.log(`Data is ${data}`);
  return data;
};

getData()
  .then(() => console.log('plete'))
  .catch(err => console.log(`oops: ${err}`));
  
console.log('this prints first since async operation is still pending');

If we have this function

const getData = () => {
  foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     return error;
   });
};

Although getData is not a promise itself, but it contains a promise, which is asyncrnous.

So what is the best way to wait for getData to return something. Async / Await doesn't work cause they work with promises.

Thanks.

If we have this function

const getData = () => {
  foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     return error;
   });
};

Although getData is not a promise itself, but it contains a promise, which is asyncrnous.

So what is the best way to wait for getData to return something. Async / Await doesn't work cause they work with promises.

Thanks.

Share Improve this question edited Dec 30, 2021 at 2:45 Soroush Bgm asked Dec 28, 2021 at 12:58 Soroush BgmSoroush Bgm 5424 silver badges18 bronze badges 4
  • 4 Add return before foo: return foo().then(...).catch(...) and call getData as getData().then(...) or await getData() – Yousaf Commented Dec 28, 2021 at 12:59
  • 2 To build up on @Yousaf's ment, currently getData() doesn't return anything. You need to make it return a Promise, so you can await it or chain .then() to it. – Jeremy Thille Commented Dec 28, 2021 at 13:01
  • 3 Note: Instead of returning error from the callback function of catch, throw it; returning an error or any value other than a rejected promise will fulfill the promise returned by getData() function which may or may not what you want. Alternatively, you could write getData() function as one liner: const getData => foo() and add the catch block in the code that calls the getData function. – Yousaf Commented Dec 28, 2021 at 13:04
  • As I understand the problem is about getting the result returned without wrapping it in a Promise. There are two ways. One is providing a callback that accepts the result: ``` const getData = (cb) => { foo() .then(result => { cb(result); return result; }) .catch(error => { return error; }); }; ``` And also you can use some blocking code that idles while the result is waiting for the assignment, but this is very bad practice I suspect. – arturasmckwcz Commented Dec 28, 2021 at 13:18
Add a ment  | 

3 Answers 3

Reset to default 3

Currently, getData() doesn't return anything. You need to make it return a Promise, so you can await it or chain .then() to it.

const getData = () => {
  return foo() // <-- here
  .then(result => {
     return result;
   })
  .catch(error => {
     throw error;
   });
};

// Now you can do :
getData().then(...)
// or :
const data = await getData();

In this case, you can also omit the curly braces and the explicit return, and make it implicit :

const getData = () => foo()
  .then(result => {
     return result;
   })
  .catch(error => {
     throw error;
   });

Hey but what's that :

.then(result => {
         return result;
})

This does nothing. It takes a value and simply returns it without doing anything. You can remove it.

You can now rewrite getData() this way :

const getData = async () => {
    try {
      return await foo()
    } catch (error) {
      throw error;
    }
}

For that matter, this :

.catch(error => { throw error; });

or this :

catch (error) { throw error; }

are also pretty useless, they just "relay" (bubble up) the error that has to be caught in the calling function.

Now it's obvious getData does pretty much only one thing, it's returning foo(), which is a Promise. It's only a wrapper around a Promise... so it's actually pretty useless.

Bottom line, detData() is useless altogether. foo is a Promise; writing a function that returns a Promise so you can use it like a Promise is just... a Promise with an extra step. Just use foo directly.

let result;
try {
  result = await foo();
} catch (error) {
  console.log(error);
}
console.log(result);

This will not work because getData is not returning a value. You can add a return statement before foo call and wait for the return value.

const getData = () => {
  return foo();
};

getData().then(data => {
  console.log(data);
}).catch(err => {
  console.log(err);
});

To wait for an operation you must return a Promise or use a callback. The code snippet below runs and should illustrate how this works. I implemented a sample foo function that is actually asynchronous (wait for 1 second before returning the data '12345'). I used async/await to illustrate how that can work, but you can equally return the result of foo and use then instead.

const foo = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('12345'), 1000);
  });
}
const getData = async () => {
  const data = await foo();
  console.log(`Data is ${data}`);
  return data;
};

getData()
  .then(() => console.log('plete'))
  .catch(err => console.log(`oops: ${err}`));
  
console.log('this prints first since async operation is still pending');

本文标签: javascriptHow to wait for a functionwhich contains promisesStack Overflow