-1

I have a method that is called in several places in the project. I've done method. the first method call do Ajax get, cache data in class property and fire callback. Second call method only call callback with cached data. I would like to add the ability to load data synchronously. Date should be returned by the method. I added an additional parameter to call {async: false}, but I wonder if there is a better solution using ES7 promises?

This is my callback solutions.

export class loadData {
    constructor() {
        this.data = [];
    }
    getData({callback, async = true}){
        let syncData = this.data;
        if( this.data.length === 0 ){
            $.ajax({
                beforeSend: authorizationManager.addAuthorizeHeader(),
                url: apiUrl + '/Data/datadata',
                dataType: 'json',
                cache: true,
                async: async
            }).done((data)=>{
                if(async) callback(data);
                this.data = data;
                syncData = data;
            });
        } else {
            if(async) callback(this.data);
        }

        if(async === false) return syncData;
    }

}
loadDataTest = new loadData();

call async

loadDataTest.getData({
    callback: (data) =>{
        console.log(data);
    }
});

call sync

let a = loadDataTest.getData({
    async: false
});
Piotr Białek
  • 2,569
  • 1
  • 17
  • 26
  • 4
    If the function is asynchronous, you cannot make it synchronous. Promises are not a way make an async function, a sync one. – thefourtheye Jul 04 '16 at 12:37

1 Answers1

2

Promises are almost always the better solution. Of course they are never synchronous, but that's usually the better solution as well. This is how it would look like:

export class loadData {
    constructor() {
        this.promise = null;
    }
    getData() {
        if (this.promise == null) {
            this.promise = Promise.resolve($.ajax({
                beforeSend: authorizationManager.addAuthorizeHeader(),
                url: apiUrl + '/Data/datadata',
                dataType: 'json',
                cache: true
            }));
        }
        return this.promise;
    }
}

And the call:

loadDataTest.getData().then((data) => {
    console.log(data);
});

I would like to add the ability to load data synchronously

I don't think you really want that. If all you want is synchronous-looking syntax for asynchronous functionality, have a look at async/await.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • thanks, but es7 async/await no returned value like this: let a = loadDataTest.getData({ async: false }) – Piotr Białek Jul 04 '16 at 14:41
  • @Whitcik: It's `let a = await loadDataTest.getData()` inside an `async function`. – Bergi Jul 04 '16 at 14:44
  • @Whitcik: Why do you believe you'd need to make the function synchronous? – Bergi Jul 04 '16 at 14:45
  • yea, it will be work, but it will be wait only in async function, i need wait in all app for data. Maybe in the future I will need to load data synchronously. – Piotr Białek Jul 04 '16 at 14:52
  • No, you won't need to. You don't want your whole app to hang. You want to make your whole app asynchronous. – Bergi Jul 04 '16 at 15:25