JavaScriptAsynchronous operation

Article directory

  • Callbacks
  • Promise
  • Async/Await – more recommended

In JavaScript, you can use asynchronous operations to handle code that needs to wait for some operation to complete before continuing. Asynchronous operations can help us avoid blocking the main thread and improve program performance and responsiveness when making network requests, reading and writing files, processing large amounts of data, etc.

Here are some common ways to handle asynchronous operations:

Callbacks

Using callback functions is a traditional way of handling asynchronous operations. You can accept a callback function as a parameter in an asynchronous function and call the callback function after the asynchronous operation is completed. For example:

function fetchData(callback) {<!-- -->
  // Asynchronous operations, such as initiating network requests
  // ...

  // Call the callback function after the asynchronous operation is completed
  callback(result);
}

//Use callback function to handle the results of asynchronous operations
fetchData(function(result) {<!-- -->
  // Handle the results of asynchronous operations
  // ...
});

I always get confused between Promise and async/await. It feels very confusing. Here is a systematic summary.

Their differences and connections:

  • async/await is syntactic sugar based on Promise. They can be used together and are not mutually exclusive.
  • Promise is a callback-based asynchronous programming model that uses the .then() and .catch() methods to handle asynchronous operations.
    async/await is a Generator-based asynchronous programming model that uses the async and await keywords to handle asynchronous operations.

Promise

Steps for usage:

  1. Create a Promise object in the function to be executed, and write the code to be executed asynchronously in the Promise constructor, that is, the asynchronous operation code
  2. After the asynchronous operation is completed, call the resolve(value) method to change the Promise object status to Fulfilled, and pass the operation result value (This value will be passed to the input parameter of the .then function); or call the reject(reason) method to change the Promise object status to Rejected, and pass the reason why the operation failed (This value will be passed to the input parameter of the .catch function)
  3. Returns a Promise object so that you can usePromise’s methods (.then(), .catch())to handle the results or errors of asynchronous operations when the function is called.

Example:

function asyncOperation() {<!-- -->
  return new Promise((resolve, reject) => {<!-- -->
    // Asynchronous operation
    setTimeout(() => {<!-- -->
      const success = true; // Assume the asynchronous operation is successful
      if (success) {<!-- -->
        resolve('Success'); // Call resolve when the asynchronous operation is successful
      } else {<!-- -->
        reject(new Error('Error')); // Call reject when the asynchronous operation fails and pass the Error object
      }
    }, 2000);
  });
}

const promise = asyncOperation();

promise.then(result => {<!-- -->
  console.log(result); // Output: Success
}).catch(error => {<!-- -->
  console.error(error); // Output: Error object or error message
});

Async/Await-more recommended

Async/await is a syntactic sugar introduced in ES2017 to handle asynchronous operations. It is based on Promises and provides a more concise code structure. Using async/await, you can use the await keyword in an asynchronous function to wait for the result of an asynchronous operation

First of all, the async function itself will implicitly return a Promise object, so you can use Promise methods (such as .then(), .catch()) to process the results of the async function >. What does that mean? That is, if you write a return statement in async, the return value will be automatically wrapped in a Promise object and become an input parameter of the Promise object.then method. Example:

async function myAsyncFunction() {<!-- -->
  return 'Hello, async/await!';
}

const promise = myAsyncFunction();

promise.then(result => {<!-- -->
  console.log(result); // Output: Hello, async/await!
});

If you do not write return in async, then async still implicitly returns a resolved Promise, but its value is undefined, as follows:

async function myAsyncFunction() {<!-- -->
  // No explicit return statement
}

const promise = myAsyncFunction();

promise.then(result => {<!-- -->
  console.log(result); // Output: undefined
});

Async/await usage steps:

  • Adding the async keyword before the function declaration indicates that the function is an asynchronous function, and you can use the await keyword to wait for the completion of the asynchronous operation.
  • Use the await keyword before an asynchronous operation to wait for the result of the asynchronous operation.
  • Use try/catch blocks to catch possible errors, where the code in the try block represents waiting for the asynchronous operation to complete, and the code in the catch block represents handling the failure of the asynchronous operation.
function asyncOperation() {<!-- -->
  return new Promise((resolve, reject) => {<!-- -->
    setTimeout(() => {<!-- -->
      const success = true;
      if (success) {<!-- -->
        resolve('Success');
      } else {<!-- -->
        reject('Error');
      }
    }, 2000);
  });
}

async function handleAsyncOperation() {<!-- -->
  try {<!-- -->
    const result = await asyncOperation(); // Wait for the asynchronous operation to complete
    console.log(result); // Processing logic when asynchronous operation is successful
  } catch (error) {<!-- -->
    console.error(error); // Processing logic when asynchronous operation fails
  }
}

In the above code, the await keyword is used to wait for the result of an asynchronous operation, assign the result to the variable result, and then process the result directly. Note that the function that uses await in the function body (i.e. handleAsyncOperation()) must be declared using the async keyword when it is defined, and its await function (i.e. asyncOperation()) should satisfy this method Will return a Promise object‘s request;

Reason:
One sentence summary: The await keyword can only be used inside an asynchronous function, and it needs to wait for the completion of a Promise object.
Specifically: In JavaScript, the await keyword is used to pause the execution of an asynchronous function, wait for the status of a Promise object to change to resolved (completed) or rejected (rejected), and then obtain the Promise object the result of.

So in order to use await, the operation to be awaited must be wrapped in a Promise object. In this way, when an asynchronous function is called and await is used to wait for the operation, the await keyword will pause the execution of the function until the state of the Promise object changes to resolved or rejected – so be sure to write resolve() and reject(), otherwise there will be no return, and await will always be stuck there and cannot be executed further.

like:

getPostDetail() {<!-- -->
  return new Promise((resolve, reject) => {<!-- -->
    const url = "/pages/test";
    const id = 1;

    wx.request({<!-- -->
      url: `${<!-- -->url}/${<!-- -->id}`,
      method: 'GET',
      success: (res) => {<!-- -->
        if (res.statusCode === 200) {<!-- -->
          const data = res.data;
          if (data.errno === 0) {<!-- -->
            this.setData({<!-- -->
              item: data.data
            });
            resolve(); // The asynchronous operation is successful, call resolve(), remember to write this! Otherwise, await will remain stuck there without returning.
          } else {<!-- -->
            console.log(data.errmsg);
            reject(data.errmsg); // The asynchronous operation fails, call reject(), remember to write this! Otherwise, await will remain stuck there without returning.
          }
        } else {<!-- -->
          reject('Request failed'); // The asynchronous request failed, call reject()
        }
      },
      fail: (error) => {<!-- -->
        console.log(error);
        reject(error); // Asynchronous operation fails, call reject()
      }
    });
  });
}


  async naviToPost(){<!-- -->
    await this.getPostDetail()
    let url = `/pages/hhh`
    const params = `?info=${<!-- -->encodeURIComponent(JSON.stringify(this.data.item))}`
    wx.navigateTo({<!-- -->
      url: url + params
    });
  },