Starting April 29, 2025, Gemini 1.5 Pro and Gemini 1.5 Flash models are not available in projects that have no prior usage of these models, including new projects. For details, see Model versions and lifecycle.
Stay organized with collections
Save and categorize content based on your preferences.
Replace callbacks by async/await for better readability and error handling in JavaScript.
You can query a model directly and test the results returned when using
different parameter values with the Cloud console, or by calling the
Vertex AI API directly.
Refactor this JavaScript code to use async/await instead of callbacks for handling asynchronous operations. The goal is to improve code readability and error handling.
Of course! Refactoring this code to use async/await is an excellent way to make it more modern, readable, and easier to maintain.
The core challenge is that the native Node.js http module is based on callbacks and streams, not Promises. To use async/await, we first need to wrap the callback-based logic in a function that returns a Promise.
Refactored Code using async/await
Here is the refactored code. It consists of two parts:
1. A new fetchDataAsync function that returns a Promise.
2. An example main function showing how to use it with async/await.
// We need the 'http' or 'https' module. This example handles both.consthttp=require('http');consthttps=require('https');/** * Fetches data from a URL and returns a Promise that resolves with the data. * This function wraps the native Node.js http/https module in a Promise. * * @param {string} url The URL to fetch data from. * @returns {Promise<string>} A promise that resolves with the response body. */functionfetchDataAsync(url){// Determine which module to use based on the URL protocolconstclient=url.startsWith('https')?https:http;returnnewPromise((resolve,reject)=>{client.get(url,(response)=>{// --- Improved Error Handling ---// Check for non-successful status codes (e.g., 404, 500)const{statusCode}=response;if(statusCode < 200||statusCode>=300){// Consume response data to free up memory before rejecting.response.resume();returnreject(newError(`Request Failed. Status Code: ${statusCode}`));}letdata='';response.setEncoding('utf8');// Good practice to set encoding// A chunk of data has been received.response.on('data',(chunk)=>{data+=chunk;});// The whole response has been received. Resolve the promise.response.on('end',()=>{resolve(data);});}).on('error',(err)=>{// This handles network errors (e.g., DNS resolution, connection refused).reject(err);});});}// --- Example Usage with async/await ---// We create an async function to use the 'await' keyword.asyncfunctionmain(){consturl='https://jsonplaceholder.typicode.com/todos/1';// Using a real API for testingconsole.log(`Fetching data from ${url}...`);try{// 'await' pauses the function until the promise is resolved or rejected.constresponseData=awaitfetchDataAsync(url);// If the promise resolves, the value is assigned to responseData.constparsedData=JSON.parse(responseData);// Often, you'll want to parse JSON.console.log('Data received:',parsedData);}catch(error){// If the promise is rejected, the error is caught here.console.error('An error occurred:',error.message);}}// Run the examplemain();
Key Improvements and Explanation
Promise Wrapper (fetchDataAsync):
async/await is syntactic sugar for Promises. Since the original http.get is callback-based, we must first "promisify" it.
The fetchDataAsync function returns a new Promise().
Inside the promise, we run the original http.get logic.
Instead of callback(null, data), we now call resolve(data) on success.
Instead of callback(err), we now call reject(err) on failure.
Readability (async function main):
The logic inside the main function now reads like synchronous code: "try to await the data, and if you get it, log it; otherwise, catch the error."
This top-to-bottom, linear flow is much easier to follow than the nested callbacks and event listeners of the original code.
Improved Error Handling:
try...catch Block: This is the standard, idiomatic way to handle errors with async/await. It cleanly separates the "happy path" (the try block) from the error-handling logic (the catch block). It catches both network errors and HTTP status code errors that we added.
Status Code Check: The original code would have treated an HTTP 404 Not Found or 500 Internal Server Error as a success, because the request itself didn't fail. The refactored version explicitly checks if statusCode is in the 2xx range and rejects the promise if it's not, which is much more robust.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-18 UTC."],[],[],null,[]]