Remember how to use async-await and encapsulate common asynchronous requests in a small program development

  es6, es7, javascript, Small program

Preface

In normal project development, you will definitely encounter the problem of synchronous and asynchronous execution. What’s more, when executing an operation depends on the result returned by the previous execution, how will you solve this problem at this time?

1. settimeout is used to make it execute asynchronously. Obviously, this is only to add it to the asynchronous task queue for execution, but there is no guarantee to wait for its return result before executing another operation.
 
 2. Or do you encapsulate the callback function yourself?  In that case, you will fall into the so-called callback hell. The code will be nested layer by layer and linked together. If the logic is slightly complicated, it will be difficult to maintain.
 
 3. Of course, promise in es6 is a very good solution to this problem. It is more perfect to cooperate with async and await in es7. await returns a promise object. The usage of Await will not be mentioned about promise and Async.

Implementation plan

First of all, the applet still does not support async and await of es7, so how can it be supported
 
 
 1. Click to download

regeneratorAnd put the downloaded runtime.js folder into the utils directory of your own applet. the package is only 20kb in total and is very small.

clipboard.png

2. introduce importregenerator runtime from' ../../utils/runtime.js' where adjustment is required
 
 3, how to package and use

Package:

const postData = async function(url, data) {
 wx.showLoading({
 Title:' loading',
 })
 let promiseP = await new Promise(function(resolve, reject) {
 wx.request({
 url: baseUrl + url,
 data: data,
 method: 'POST',
 header: {
 'content-type': 'application/json',
 'access-token': wx.getStorageSync('token')
 },
 success: function(res) {
 wx.hideLoading();
 if (res.statusCode === 200) {
 resolve(res)
 } else {
 reject(res.data)
 }
 },
 fail: function(err) {
 wx.hideLoading();
 reject(err)
 if (err.code === 401) {}
 }
 })
 })
 return promiseP
 }
 module.exports = {
 postData
 }

Use:

import regeneratorRuntime from '../../utils/runtime.js';
 const app = getApp(),
 postData = require('../../service/koalaApi.js');
 
 
 async demo() {
 await postData(app.globalData.baseUrl + '/test',{
 data: {}
 }).then((res) => {
 console.log(res)
 })
 }

The following is a more perfect package, including the processing and simplification of various wrong judgments, which can be flexibly invoked through parameter transmission.

//current host
 const url_host = require('API.js').host
 //current version
 const currentVersion = require('util.js').currentVersion
 //Current path
 import { currentPagePath } from 'util.js'
 
 //Call fetch method, and then pass it in chain in turn
 //url, method, header, data, loading (whether loading is displayed or not)
 
 function fetch(url, method, header, data, loading) {
 //Judge the problem of passing undefined to the server
 let fetchP = new Promise(function (resolve, reject) {
 if (loading) {
 wx.showLoading({
 icon: 'loading'
 })
 }
 if(data && data.unionId && typeof data.unionId === "undefined"){
 wx.hideLoading()
 return reject({
 ok:false,
 error: 'unionId -> ' + typeof data.unionId
 });
 }
 wx.request({
 url: url_host + url,
 method: method ?  method : 'GET',
 header: {
 Content-type':' application/json',//default value
 'version': currentVersion,
 'pagePath': currentPagePath()
 },
 data: data,
 success: function (res) {
 if (res.statusCode < 500) {
 resolve(res.data)
 } else {
 showError()
 reject(res.data)
 }
 },
 fail: function (err) {
 showError()
 reject(err)
 },
 complete: function (comp) {
 if (loading) {
 wx.hideLoading()
 }
 }
 })
 })
 return fetchP
 }
 
 //The server has deserted
 function showError () {
 wx.hideLoading()
 //Get header file path
 wx.navigateTo({
 url: '/pages/serverError/serverError',
 })
 }
 
 module.exports = {
 fetch
 }

Thinking

1. Why can async/await be used when the regeneratorRuntime is introduced? Don’t you need to cooperate with babel?

What did the regeneratorRuntime do?

Summary

1. first understand what babel and polyfill do respectively;

Babel is a widely used transcoder. Babel only converts the new JavaScript syntax by default, not the new API.
 
 For example, global objects such as Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise, and some methods defined on global objects (such as Object.assign) will not be translated.
 
 If you want to use these new objects and methods, you must use babel-polyfill to provide a gasket for the current environment.

2. Polyfill is the code used to implement the native API that the browser does not support.

3. After understanding the above meaning, it is also necessary to understand that babel-polyfill adds all to your js file, and the current runtime will judge which ones you need to load and load selectively, and the latter will not pollute the global variables. Here, the regeneratorRuntime is finally converted into the generator of es6 for use. Specifically, you can go to babel’s website and enter the relevant code to see the final converted code.