0

I got something like this:

    methods: {
        process: function process(id) {
            this.$http.post('controller/process', { id: id }).then(function (res) {
                if (res.data.items > 0) {
                    this.process(id);
                } else { 
                    return true;
                }
            }, function (data) {
                this.$notify(data, 'danger');
                this.progress = false;
            });
        },
        run: function run($id) {
            this.busy = true;   
            this.process($id);  
            this.busy = false;  
        }

    },

Alright - this is some JavaScript using Vue.js and vue-resource to do am API call (process). The API returns the number of elements to be processed. If this number is > 0, the function should be executed again. This works fine.

Now I would like to solve the following:

Executing the run function should set this.busy = true. After the function process is done processing all items, this.busy should be set to false.

So I read something about promises - but I still don't get how I could use them in this case.

SPQRInc
  • 162
  • 4
  • 23
  • 64
  • If you return the promise from that function, you can execute your code after your recursive function returns with a `then` statement. e.g. `YourClass.process(id).then(result => doSomethingWith(result))`. If you do it this way, you do not need to use the busy flag. – mjuopperi Sep 07 '17 at 10:40
  • As `process` function is a promise, then you can do`this.process($id).then(function() { this.busy = false; } ); ` – Mohamed Shaaban Sep 07 '17 at 10:42

2 Answers2

1

You would need to:

  • return the promise (both in process as in the then callback)
  • use arrow functions when you want to have access to the same this value.

Suggested code:

methods: {
    process: function process(id) {
        return this.$http.post('controller/process', { id: id }).then((res) => {
            if (res.data.items > 0) {
                return this.process(id);
            }
        }, (data) => {
            this.$notify(data, 'danger');
            this.progress = false;
        });
    },
    run: function run($id) {
        this.busy = true;
        this.process($id).then( _ => this.busy = false);  
    }
},

It should be noted however that introducing the busy flag should not be necessary when you stick to the promise pattern. It should certainly not be used to somehow wait for the process to complete. For that purpose you should stick to the then callback system (or use the async/await syntax, which comes down to the same thing).

trincot
  • 317,000
  • 35
  • 244
  • 286
-3

Use deferred:

methods: {
    process: function process(id) {
        var deferred = $q.defer();
        this.$http.post('controller/process', { id: id }).then(function (res) {
            if (res.data.items > 0) {
                this.process(id);
            } else { 
                return deferred.resolve(true);
            }
        }, function (data) {
            this.$notify(data, 'danger');
            this.progress = false;
            return deferred.resolve(true); //if not will fail promise
        });

        return deferred.promise;
    },
    run: function run($id) {

        this.busy = true;   
        this.process($id)
            .then(
                function() { //executes when resolve
                    this.busy = false;  
                },
                function() {
                    //executes when you run deferred.reject() in process method
                }
        );  

    }

},

I do it without test.

Mork
  • 365
  • 5
  • 18
  • 1
    You are introducing the [deferred anitpattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it). To avoid this, the promise itself should be returned, as indicated in other comments and in what I answered. – trincot Sep 07 '17 at 10:52
  • I don't know whats the problem, I'm only explaining how to begin to solve their problem. If he want to refactor later to make good practice code will be appreciate. He are asking to better solution, answer question and all will learn. – Mork Sep 07 '17 at 11:05