I’ve been following the Nuggets for so long, I haven’t started writing because the blogger is either working overtime or on his way to work overtime, la la la! Less nonsense, enter the body……

A few days ago, a friend encountered a problem, is the legendary callback black hole, said the black hole is a bit of exaggeration, is two layers. To give some background, a VUE project first wrote two public methods in the tool methods:

  • (1) Locate the interface to obtain the longitude and latitude,
  • (2) Then use the obtained latitude and longitude to perform the next asynchronous acquisition of city information, including city ID, city name, etc.

Of course, these two methods are written in the tool script. This method is then called in the.vue single-file component and the city ID is retrieved.

What’s the worst thing you can do in this situation? This is the

function a(){// async success b(); }function b(){// execute asynchronous retun obj; }Copy the code

Of course, in normal circumstances, there is no problem, but the partner is to call in the component, so that you can not get the value, let alone two asynchronous, even if there is an asynchronous is undefined

Little friend puzzled, how can not get it? How can I get it? After a long struggle, ask me. First, I looked at the script and told him about the problem of synchronous asynchrony. If you want to get the value, you have to transfer asynchrony.

The async-to-synchronous methods are generator functions, the yield keyword, and the latest async and await methods, which claim to be perfect solutions to callback black holes. There are other welcome gods to add.

Back to business, I started to change the code for my friend. Start with the original code:

function wxGetLocation() {
         wx.getLocation({
             success: function(res) { var lat = res.latitude; Var LNG = res.longitude; // Latitude is 90 ~ -90 var LNG = res.longitude; // The longitude is a floating point number ranging from 180 to -180. var arr = [];if (lat && lng) {
                     changeLonLat(lon,lat)
                 } else{// Default latitude and longitude changeLonLat(lon,lat)}}, cancel:function(res) {
                 alert('User denies permission to obtain location');
             },
             fail: function(e) {
                 alert('Location failed ~'); }})})}function changeLonLat(lon, lat) {
      axios.get('/lonLatGetCityMessage/? lon=' + lon + '&lat='+ lat).then(response => {// a series of operationsreturn cityParams;
             
         })
         .catch(error => {
             alert('error' + JSON.stringify(error))
         })
 }
Copy the code
Var a = wxGetLocation(); alert(a) // of course undefinedCopy the code

At the beginning, I told my friends about the idea of using async await to mutate step as synchronization. And then while changing, of course, is in his basis to add two keywords, in need of asynchronous data to add two keywords, no problem. But it didn’t work out.

So I’m thinking what’s the problem? The train of thought is not wrong; Thinking that in cases where asynchronous callbacks are needed, methods after await need to return promises!

So I just kept building on that. Still not solved. Now that promise’s here, what’s the problem?

Think of the central idea is the mutation step for synchronization, that are synchronous, but also need a set of a?

So I pushed his code away and started over!

Perfect finish (attached code)!

Run with confidence, huh? I am sure that I am right, therefore I am underpaid

Through alert, it is really according to their own ideas to go, perform asynchronous data before returning.

The resolve parameter of a promise has only one. Bullying me is not a new Promise. Sure enough, after Baidu found that promise can return only one parameter. Fix it again, test perfect. The following code:

function wxGetLocation() {
    return new Promise((resolve, reject) => {
        wx.getLocation({
            success: async function(res) { var lat = res.latitude; Var LNG = res.longitude; // Latitude is 90 ~ -90 var LNG = res.longitude; // The longitude is a floating point number ranging from 180 to -180. var arr = [];if (lat && lng) {
                    arr = [lng, lat];
                    resolve(arr);
                } else{// Default latitude and longitude arr = ['120.678923'.'31.324308']
                    reject(arr)
                }
            },
            cancel: function(res) {
                alert('User denies permission to obtain location');
            },
            fail: function(e) {
                alert('Location failed ~'); }})})}function changeLonLat(lon, lat) {
  undefined
    return  axios.get('/lonLatGetCityMessage/? lon=' + lon + '&lat='+ lat).then(response => {// a series of operationsreturn cityParams;
             
         })
         .catch(error => {
             alert('error' + JSON.stringify(error))
         })
}
Copy the code
// Call method:let lonAndLat;
    await wxGetLocation().then(async (arr)=>{
         lonAndLat =  await changeLonLat(arr[0], arr[1])
    },async (arr)=>{
         lonAndLat = await changeLonLat(arr[0], arr[1])
   });

Copy the code

I didn’t write this method seriously in my own project (I have been maintaining the ancient content). By helping my friends solve this problem, I found that although I know how to do it in general, I still need to maintain a lot of details. I can only say keep going!

Ps: just after dinner, eat so full!!