问题
Trying a little hack here with cloud functions but can't seem to figure out what the issue is.
I'm currently using now.sh to host serverless functions and would like to call 1 function from another. Lets say I have 2 functions declared fetchData
& setData
. When the setData
function is called it processes some data and then calls the fetchData
function.
export const setData = async (req: Request, res: Response) => {
await axios.post(
fetchDataEndpointUrl,
{
params: {
key,
},
},
);
return res.json({
payload: true,
});
}
The above code works fine but the time taken for the entire operation to complete would be setData function call + the time taken for the fetchData function call to complete. What I'm trying to do is make a call to fetchData
without having to wait for it to complete essentially removing the await
in the axios call. I've tried removing the await
but the call just ends abruptly when the setData
call ends. Is there a way to decouple this action and not have to wait for the setData
function to complete?
回答1:
The summary of your question appears to be that when you call a Cloud Function, you want it to be able to return a value to its caller while simultaneously performing background work such as calling another service and waiting for a response.
When you return a value to the caller for a Cloud Function, that is the end of the life span of the Cloud Function. You can not be assured of any kind of life in the Cloud Function beyond the return.
This is documented here.
The text (in part) reads:
A function has access to the resources requested (CPU and memory) only for the duration of function execution. Code run outside of the execution period is not guaranteed to execute, and it can be stopped at any time. Therefore, you should always signal the end of your function execution correctly and avoid running any code beyond it.
Another part of the question is what if we want to have our Cloud Function make an asynchronous REST call where we don't care about waiting for the response. Can we return from the Cloud Function without waiting for the nested REST call to complete?
The answer is maybe but it will depend on the nature of service being called and how we are calling it. To appreciate the nuances in this remember that JavaScript is a single threaded language. There aren't multiple threads of execution. In our JavaScript app, only one thing will ever happen at a time. If we make an asynchronous REST call and don't care about a reply but (obviously) do care that the request has been sent then we need to synchronously send the request before we terminate the Cloud Function. This can get tricky if we start using library packages without delving into their natures. For example, a REST call might include:
- A socket connection to the partner
- A transmission of the outbound request
- A callback when the response is received
We need to be absolutely sure that the transmission has happened before we end the top level Cloud Function call. In addition, if we do end the top level Cloud Function call, that may very well tare down the socket used for the response. This could result in an exception in the called REST service that now is unable to return its 200 response.
To run work where we don't need to nor want to wait for a response, GCP provides an architected solution for this. It is called "Cloud Tasks" (see Cloud Tasks). Within your Cloud Function, you would define a request to call your nested service asynchronously and hand that request off to Cloud Tasks to execute. Cloud Tasks would acknowledge receipt of the request to execute and you can now be assured that it will and can return at the highest level.
来源:https://stackoverflow.com/questions/59511646/call-cloud-functions-without-waiting-for-response