0

Any ideas of how to fix this 'f' function(paralell), the output nedd to look

f's activity starts.

f's activity starts.

f's activity starts.

f's activity ends.

f's activity ends.

f's activity ends.

Done.

Sometimes works, but not always, any ideas of how to fixed(the task is to not modify the 'f' function).

Thank you.

function f(cb) {
  console.log("f's activity starts.");
  var t = Math.random() * 500; //gives a num between 0 and 1000

  function onActivityDone() {
    console.log("f's activity ends.");
    if (cb) cb();
  }
  setTimeout(onActivityDone, t);

}

function final() {
  console.log('Done');
}

function first() {
  final();
}



f()
{     
f()
{
    f(first)
  };
};
3
  • 1
    In my opinion it can't be done without modifying f function... If var t is 0, then onActivityDone is triggered immediately after f finished execution. Math.random() is random, so you don't have any control on the time of execution of onActivityDone function, and the same with cb. The only knowledge is that it will happen within a second. Commented Jan 2, 2014 at 3:56
  • That's what I think too, but the professor says that is possible to do it, and that what i try to do. Commented Jan 2, 2014 at 4:06
  • 1
    possible duplicate of Callback javascript function parallel Commented Jan 2, 2014 at 6:39

3 Answers 3

1

This bit looks somewhat strange

f()
{     
f()
{
    f(first)
  };
};

It looks like you're trying to do something like this

f(function() {
  f(function() {
    f(first);
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

f accepts undefined arguments, so the code actually works. It simply does not what was probably intended ;)
Yes the code works, but print a differente output, the idea is to star all at the same time, then end all at the same time and lastly print done
0

Based on the comments I've edited my answer:

function f(cb) {
    console.log("f's activity starts.");
    var t = Math.random() * 500; //gives a num between 0 and 1000

    function onActivityDone() {
        console.log("f's activity ends.");
        if (cb) cb();
    }
    setTimeout(onActivityDone, t);
}

function final() {
    console.log('Done');
}

var iterations = 1000,
    ended = 0,
    i;

function first() {
    ended++;
    if(ended == iterations) {
        final();
    }
}

for(i = 0; i < iterations; i++) { f(first) }

The idea is to run final function only when 1000th callback is fired. Also setTimeout with 0 time will always wait till parent thread will end - according to MDN docs:

It's important to note that the function or code snippet cannot be executed until the thread that called setTimeout() has terminated.

So this is why all the 'starts' are before 'ends'.

3 Comments

Carlos, thanks for your help I try your code and I get the same output, for some reason sometimes your code and my code prints 'done' between 'fs activity ends' and the idea is to print 'done' after all activities are done.
Can you change the final and first functions?
Once again: Can you change the final and first functions?
0

maček gave you the answer to your problem.

What your code does is equivalent to :

f();
f();
f(first);

The braces are simply opening unnecessary code blocks.

EDIT: after reading your comments, I think you might want to do something like this:

function trace (msg)
{
    var d = new Date();
    var h = d.getHours();
    var m = d.getMinutes();
    var s = d.getSeconds();
    console.log (h + ":" + m + ":" + s + " " + msg);
}

var Synchro = new function () {
    this.num_funs = 0;
    this.funs = {};

    this.register = function(fun)
    {
        this.funs[this.num_funs] = fun;
        trace ("activity "+this.num_funs+" registered.");
        this.num_funs++;
    };

    this.start = function()
    {
        console.log("launching "+this.num_funs
            +" activit"+(this.num_funs == 1 ? 'y' : 'es'));

        this.num_active = this.num_funs;
        for (var i in this.funs)
        {
            var t = 2000 + Math.random() * 8000; // delay from 2 to 6 seconds
            setTimeout(onActivityDone, t);
        }

        var _this = this;
        function onActivityDone()
        {
            if (--_this.num_active == 0)
            {
                trace ("all functions complete")
                for (var i in _this.funs) _this.funs[i]();

            }
            else trace ("still "+_this.num_active+" to go");
        }
    };
} ();

function fun1() { trace (' hi from fun1'); }
function fun2() { trace (' hi from fun2'); }
function fun3() { trace (' hi from fun3'); }

Synchro.register (fun1);
Synchro.register (fun2);
Synchro.register (fun3);
Synchro.start();

5 Comments

The only problen that I have is that I need to star all functions(3) at the same time and then ends all, and print Done after all function are finished. f's activity starts. f's activity starts. f's activity starts. f's activity ends. f's activity ends. f's activity ends. Done.
Thanks for your code, i will try to understand it first and then try to modify my code.. thank you.
You're welcome. The JSfiddle makes pretty clear what my code does, but I'm not sure that's what you wanted.
im really new at this, at what I need is only to print firs, f activy start(3 times) then print f activity ends(3 times) and then print Done.
try this fiddle, it will display the messages you expect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.