front-End JS traditional asynchronous solution timely callback, but our dear Es6 has added three new solutions:Promise Generator
-Async
Before the project has been used promise to solve, Vue project in the Axios is also the return of promise object, Async is actually generator grammar sugar, this time we do not speak promise and generator, Because the async has always been understood not very thoroughly, take an example of a project to transform the async:
This project uses the Vue+elementui, here is a CRM manages the system, the customer file Information Management module, because the information is quite large, divides into three tab pages, three individual interface information, naturally divides into three subcomponents.
()
When the parent component clicks on the Submit button, three interfaces are requested first interface information needs to be validated, 23rd interface information does not need to be validated only after the first request succeeds, the following two are requested, and the previous page is returned when the last two requests succeed.
Index.vue
Parent Component Click submit Trigger Child component Submit Event
Submitall () {this
. $refs. Baseinfo.submit ()
/*if (this.buyer_info) {
this.$ Refs.businessInfo.submit () this.
$refs. Chaininfo.submit ()
$router. Go ( -1)
}*/
},
Baseinfo.vue
* Submit the first subassembly information *
submit () {this
. $refs [' baseform '].validate (valid) => {
if (valid)
{ This.handleparams ()
axios.post ('/v2/buyer/createbuyerinfo ', this.baseform). Then (res =>{
if ( Res.data.code = = 1 {this
. $emit (' IsOK ', true)
} else {this
. $message ({
showclose:true,
Message: ' ${res.data.message} ',
type: ' Warning '}}}
)
} else {
console.log (' Error submit!! ');
return false;
}
);
Index.vue
The parent component listens for the IsOK event of a subassembly
<base-info:i18n= "i18n" ref= ' baseinfo ': isedit= ' isedit ' @isOK = ' isOK ' @tot = ' tot ' ></ Base-info>
Child Component Basic Information request passed, followed by other child component events
IsOK (val) {
if (val) {this
. $message (' success ')
this.$ Refs.businessInfo.submit () this.
$refs. Chaininfo.submit ()
the. $router. Go ( -1)
}
},
The submit event in Businessinfo.vue and Chaininfo.vue is two Axios requests.
Submit () {
this.businessForm.purchase && this.handlerparams ();
Axios.post ('/v2/buyerbusiness/createbusiness ', {... this.businessform,... {buyer_id:this. $route. query.id | | this.buyer_info.id, is_edit:this. $route. Query.id}}). Then (res =>{
if (Res.data.code = 1) {
} else {this
. $message ({
showclose:true,
message: ' Business information $ {res.data.message} ',
type: ' Warning '}}}}
,
This is a cumbersome way of writing, and one problem is that it is possible to return to the previous page when a subassembly request has not been completed.
Here we can use Promise.all to solve, here we try to async/await, modify the following: solution
Index.vue
IsOK (val) {
if (val) {this
. $message (' success ')
const Reqinorder = async () =>{
try {
const a = await thi S. $refs. Businessinfo.submit ()
Const B = await this. $refs. Chaininfo.submit ()-
$router. Go ( -1)
} catch (e) {
console.log (e)
}
}
Reqinorder ()
}
Businessinfo.vue and Chaininfo.vue
Where fetch is a function of their own encapsulation, return is a Promise object of
course Axios itself return is a promise object, directly use can
submit () {
This.businessForm.purchase && this.handlerparams ();
return fetch ('/v2/buyerbusiness/createbusiness ', {... this.businessform,... {buyer_id:this. $route. query.id | | this.buyer_info.id, is_edit:this. $route. query.id}})
},
Fetch.js
Export default function Fetch (URL, params) {return
new Promise (Resolve, Reject) => {
axios.post (URL, params) . Then (response => {
resolve (response.data);
}, err => {
reject (err);
}). catch ((Error) => {
reject (Error)})}}
There is also a problem here, because the Businessinfo.vue and Chaininfo.vue two interfaces are not sequential, and we have previously written is a secondary request, that is, the first interface request is completed before requesting a second interface, this is unreasonable. Optimization Scheme
Index.vue
IsOK (val) {
if (val) {this
. $message (' success ')
const Reqinorder = async () =>{
try {
concurrent processing request (Error, is actually renewed) let
businesssubmit = the $refs. Businessinfo.submit () let
chainsubmit = this. $refs. Chaininfo.submit ()
const A = await businesssubmit
Const B = await chainsubmit this
. $router. Go ( -1)
} catch (e) {
Console.log (e)}}
reqinorder ()
}},
Two ways to resolve concurrent requests
Concurrent two kinds of writing
//writing a let
[foo, bar] = await promise.all ([Getfoo (), Getbar ()]);
Two let
foopromise = Getfoo ();
Let barpromise = Getbar ();
Let foo = await foopromise;
Let bar = await barpromise;
Please correct me if you have any questions.
—————————————— I'm a split line ——————————————-
found that the above concurrent processing is problematic, businessinfo and chaininfo two requests are renewed, that is Businessinfo request after the request chaininfo. The requirement is that the first request is renewed, the request is successful, processing two concurrent requests, and then processing the related business
Because the first request is handled separately in the child component with the relevant validation rules and processing, the isOK event is emit to the parent component after success.
IsOK (val) {if (val) {This.reqinorder ()}}, Async Reqinorder () {try {//process concurrency let children =
. $refs. Businessinfo,this. $refs. Chaininfo]//Here the array traverses the execution async, and the map returns an array with the Promise object as the key
Const Datapromises = children.map (Async child => {Const RESPONSE = await child.submit () Return response}) let Codearr = []//Process P Romise Array gets resolve result for (const datapromise of datapromises) {Codearr.push (AWA It datapromise)}//processing results after processing related data let flag = Codearr.every (ite
M =>{return Item.code = = 1}) if (flag) { This.fullscReenloading = False This.getcount ()} catch (e) { Console.log (e) this. $message (e)}},