I hope that through the following cases can be a primer, so that we have a clearer understanding of promise.

1. Share login status in wechat mini program

Usually, after users open the mini program, they will enter our index home page. However, there are also cases that users will enter the mini program through the link shared by friends, and the link shared is most likely not the home page. It is obviously unreasonable to invoke login on multiple pages.

The login is usually put in the onLaunch method in app.js, which is the hook function that will be executed first when entering the applet. The onLoad method of the page page is then executed. This procedure is invoked synchronously following. At the same time, the login is an asynchronous request, meaning that the login is not complete when the onLoad method of the page is called.

So the first thing that comes to mind is, is there a way in app.js to sort of tell the following page that you can load and execute your onLoad method after I’ve logged in here? Here micro channel small program does not have this method!

Here we can use promise to solve this problem and go directly to the code:

//app.js
App({
  onLaunch() {
    this.globalData.loginState = new Promise((resolve, reject) = > {
      wx.login({
        success: (res) = > {
          // Add the user data from the server side of your project
          resolve(data);
        },
        fail: (res) = >{ reject(); }}); }); },globalData: {
    loginState: null,}});Copy the code
//index.js

var app = getApp();
Page({
  onLoad() {
    this.globalData.loginState
      .then(() = > {
        / /... Successful business logic
      })
      .catch(() = > {
        / /... Failed business logic}); }});Copy the code

The onLaunch in the app will be executed first, the incoming function will be called synchronously, and the login request will be initiated synchronously. So loginState is a promise. We know that promises are stateful and cannot be changed once the state changes. The business logic code in the page does not care whether loginState is in a pending or failed state, because if it is pending, I wait for you. If it is pending, I do different processing. It is worth noting that a promise can call THEN multiple times, which means that the same onLoad code will still work in other pages. Whether this page is the first to enter the page, or the user clicks the jump to enter the page. Because my main body is going to be loginState, this promise.

2. Unified control and judgment of operation rights

Requirements:

  • Users are divided into member users and non-member users.
  • Member users can download videos as many times as possible
  • Non-member users have the experience times of downloading videos, and each time they use the video, the popup window indicates the remaining experience times.

Encapsulation of the verification method for this function:

async function permissionHandler() {
  const { content } = await api();
  // Member users
  if (content.isVip) {
    return Promise.resolve();

    // Non-member users
  } else {
    // There are times of play
    if (content.times) {
      return MessageBox.confirm('Number of remaining experiences${content.times}`);

      // There are no experiences
    } else {
      return Promise.reject(); }}}/ / call
permissionHandler()
  .then(() = > {
    // Download the video
  })
  .catch(() = > {
    // Do not download the video
  });
Copy the code

The async function is used here, which is also based on Promises. First await an asynchronous request, whether the current user is a member user or not. If the user is a member, it will directly return a promise that the status is successful. Remember that in async functions, the return value must be a promise. Resolve (undefined) is the same as return promise.resolve (undefined). My advice is to always write it explicitly for easy maintenance.

Then the other case goes to the non-member, and if there is no number of experiences, it directly returns a failed state promise, same principle as above. If there is a number of experiences, messagebox.confirm () is returned, which is a promise of waiting state. Since the state is waiting, it is not determined whether to download the video under my business logic. The question is when to decide, exactly after the popover hit OK or cancel. After clicking OK, messagebox.Confirm () will change from waiting to success, and then my business logic of downloading the video will be executed, while clicking Cancel will be the opposite.

3. Submit the form

  • Check sensitive words before submitting the form
function sensitiveWordCheck() {
  return (
    apiSensitive()
      // Verify no sensitive words
      .then(() = > {
        return Promise.resolve();
      })
      // There are sensitive words
      .catch(() = > {
        return Promise.reject(); })); }function submit() {
  sensitiveWordCheck()
    .then(() = > {
      / / submit
      return apiSubmit();
    })
    .then(() = > {
      // Submission succeeded
    })
    .catch(() = > {
      // Commit failed
    });
}

submit();
Copy the code

First of all, I want clean mainline logic in submit(), so the sensitiveWordCheck is written as a method sensitiveWordCheck(), because it needs to include calls to the API (sensitive words are the ones that hand the content to the back end) called apiSensitive(), You also need to include filtering for sensitive words. Therefore, I do not want anything about sensitive words to appear in the Submit method, which will make my main line unclear.

Now take a closer look at the sensitiveWordCheck() code.

function sensitiveWordCheck() {
  return apiSensitive().then().catch();
}
Copy the code

Remember that apiSensitive() is an asynchronous request that returns a promise, then calls then and returns a Promise. Since it’s a Promise, you can call catch again and still return a Promise. So the whole return is the promise after calling the catch. We should know that the first thing we should think about when we get a promise is what state it is, and then carry out the following analysis and processing. Let’s start with the different states of apiSensitive()

  1. pending -> fulfilled

In this case, the successful state means that there are no sensitive words, and you can continue to submit the form. In this case, the following codes have the same effect:

function sensitiveWordCheck() {
  return apiSensitive()
    .then(() = > {
      return Promise.resolve();
    })
    .catch(() = > {});
}
/ / is equivalent to
function sensitiveWordCheck() {
  return apiSensitive()
    .then(() = > {
      return; // Return can be omitted
    })
    .catch(() = > {});
}
If you have no other logic to deal with
function sensitiveWordCheck() {
  return apiSensitive().catch(() = > {});
}
Copy the code

Resolve (undefined) if the callback does not return a promise. Resolve (undefined) if the callback does return a promise.

  1. pending -> rejected

If it’s a failed state, it goes into a catch, and even though the then method has a second callback that goes back to the failed state, my habit is to always catch an error, so if a promise is caught, then the error is handled. If there continues to be a then, it will be executed. Unless a failed promise is returned in a catch. In our example we show return promise.reject (); It’s telling the back that this failed, even though I caught this error here, because I might have something else to do. For example, I add a little logic: if there are sensitive words, a dialog box will pop up, asking whether the sensitive words need to be filtered out. If you select certain words, you will help filter them

<script>111</script>
function sensitiveWordCheck() {
  return (
    apiSensitive()
      // There are sensitive words
      .catch(() = > {
        return MessageBox.confirm('Does it automatically filter sensitive words? `)
          .then(() = > {
            / /... Automatic filtering logic for sensitive words
            return Promise.resolve()
          })
          // The catch can be omitted if there is no additional logic, which is equivalent to passing the error on later
          .catch(() = > {
            return Promise.reject() }) ; })); }Copy the code

Catch is still a promise, so its state is determined by the return value of the callback in the catch, which is the same as then.