简体   繁体   中英

How to make axios synchronous

I'm using axios to check if an alias has not already been used by another in the database.

Problem : The ajax call doesn't wait for the server response to execute the remaining code.

The code looks like :

export default {
    data () {
        return {
            id: null,
            alias: null,
            valid: true,
        }
    },

    methods: {
        // triggered by the save button
        save () {
            this.valid = true;
            console.log('before checking');

            this.checkUniqueness();
            // other validations here

            if (this.valid) {
                console.log('3. checked valid, can save now');
                // save now
            }
        },

        checkUniqueness () {
            axios.get('/api/unique/alias', {
                params: {
                    id: this.id,
                    alias: this.alias,
                }
            })
                .then((response) => {
                    console.log('2. server response:' + response.data.unique)
                    this.valid = response.data.unique;
                });
        },

    },
}

The console shows the following result:

1. before checking
3. checked valid, can save now
2. server response:false

I cannot move the code of the save() method into .then because I do other validations on the input data such as alpha-numeric characters, minimum of characters...

I was able to delay the 3rd part ( if (this.valid) { ) using set setTimeout but it's not the best solution. what if the server takes more or less than the defined waiting time..

Question Is there a way to make this call sequential (1, 2, 3) instead of (1, 3, 2)?

You can't (or at least really shouldn't) make it synchronous, so you'll need a different way forward.

One idea: return the promise from Axios:

checkUniqueness () {
    return axios.get('/api/persons/unique/alias', {
        params: {
            id: this.id,
            alias: this.alias,
        }
    })
    .then((response) => {
        console.log('2. server response:' + response.data.unique)
        this.valid = response.data.unique;
    });
}

and then call then() on it in save() :

this.checkUniqueness()
.then((returnVal) => {
   // other validations here
  //  save
})
.catch(err => console.log("Axios err: ", err))

You could even do all your checking on one place if you returned the value from Axios's then() rather than setting the flag:

.then((response) => {
    console.log('2. server response:' + response.data.unique)
    return response.data.unique;
 });

then in save:

this.checkUniqueness()
.then((valid) => {
    if (valid) // do something
   // other validations here
   //  save
})

If you just do what JS docs ( mozilla ) show you can treat Axios as just another promise. Be careful about making the request synchronous bc it can freeze the UI and the rest of your app.

       async save () {
            this.valid = true;
            console.log('before checking');

            const isUnique = await this.checkUniqueness();
            console.log(isUnique); // => value waited for and returned from this.checkUniqueness()
            // other validations here

            if (this.valid) {
                console.log('3. checked valid, can save now');
                // save now
            }
        }

axios.get(...) returns a promise (a task that is promised for later) and you can wait the interpreter untill this promise ends with an await word in ES6+ :

let response = await axios.get(...)

but axios.get(...) returns the response while axios.get(...).then(...) returns what you intended to return. so if you dont return anything in then part it will be undefined :

let response = await axios.get(...).then() // nothing returns in then
console.log(response) // undefined

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM