async and await are used in 21 Vue to realize synchronization and asynchrony
The scenario is as follows: the current logic is to modify the series.data in echart's option according to the return data of the back-end API, and then execute the setOption method to render the icon. However, the problem is that the back-end API can return data normally, but according to the display of the console, the setOption method is executed first, and then the API data is assigned to series.data, Therefore, the chart cannot render the desired data. The code is as follows
Copy code
methods: { initChart() { this.chart = echarts.init(document.getElementById(this.id)); fetchOverview().then(response => { console.log('1--') console.log(response.items) console.log('2--') this.option.series[0].data = response.items }).catch(error => { console.log(error); }) console.log('a----') console.log(this.option.series[0].data) console.log('b-----') this.chart.setOption(this.option); }, }
Copy code
The browser console output is as follows
Note that fetchOverview is executed asynchronously by default, and the contents behind the fetchOverview function are not blocked. Therefore, a - and b - are output first. If fetchOverview is changed to synchronous execution, async and await should be used in combination
1.async/await scenario
This is a solution to the asynchronous problem with synchronous thinking. The current interface call needs to wait until the page is rendered after the interface returns the value.
2. Explanation of terms
async
async It is used as a keyword in front of the function to indicate that the function is an asynchronous function because async Asynchronous means asynchronous function, which means that the execution of the function will not block the execution of the following code, async Function returns a promise Object. async Function is also a function. We can use it as we normally use it. We can use it directly with parentheses .then Method (Reference) https://www.jianshu.com/p/ab767311589d)
await
Await means wait. It means that the code needs to wait until the function behind await runs and returns the result before continuing to execute the following code. This is the effect of synchronization. What is it waiting for and what is it followed by? In fact, it can be followed by any expression, but we put more expression of promise object (I immediately executed. then in this way). Note that the await keyword can only be placed in the async function!!!
So the modified code is as follows
Copy code
methods: { async initChart() { this.chart = echarts.init(document.getElementById(this.id)); await fetchOverview().then(response => { console.log('1--') console.log(response.items) console.log('2--') this.option.series[0].data = response.items }).catch(error => { console.log(error); }) console.log('a----') console.log(this.option.series[0].data) console.log('b-----') this.chart.setOption(this.option); }, }
Copy code
The console output is as follows
Meet expectations!!!
Note: the functions executed in the mount phase of vue are executed sequentially and will not be blocked. Therefore, if you want the functions in the mount phase to be blocked, you need to write an additional async function, then write the functions to be executed synchronously, and then call this additional written function in the mount phase, such as
async renderData() { await this.getBusinessLinesAndDepartments() if (this.workFlowData) { // View or approve process _.forEach(JSON.parse(this.workFlowData.workflowSteps), (step) => { if (_.values(step)[0].active) { this.currentStep = _.keys(step)[0] } }) this.form_temp = JSON.parse(this.workFlowData.meta) this.initBusinessLines(false, this.form_temp.department) } else { // Create process this.currentStep = 'apply' } await this.permissionCheck() }, }, mounted() { this.renderData() },
If written
mounted() {
this.renderData()
If this.permissionCheck() is written like this, permissionCheck will be executed before renderData (the backend will be requested to get data)
},
Copy code
//Notice async before response
await searchService(search_key).then(async response => { var service_one_id = response.results[0].id // _.forEach(response.results, (item) => { // service_ids.push(item.id) // }) await deleteService(service_one_id).then(response => { # If async is off in front of the response, the await will report an error // Set new approval information variable _.forEach(workflowSteps, (step) => { var step_name = _.keys(step)[0] var step_info = _.values(step)[0] if (step_name == 'op_approve') { step_info['approve_result'] = true } if (['delete_service', 'end'].includes(step_name)) { // Next step through step_info['active'] = true } workflowStepsParam.push({[step_name]: step_info}) }) }).catch(error => { workflowStepsParam = workflowSteps console.log(error) }) }).catch(error => { workflowStepsParam = workflowSteps console.log(error) })