开发者

How do I send a condition test to a Javascript function and not only it's result?

I had the idea about making a small jQuery plugin but there's something I don't know how to do it without having to rely on eval.

Here's the code:

            var testMe = 1;

            $.extend({
                once : function( condition, duration, callback) {
                    window[ "once" ] = window.setTimeout(function() {
                        if ( condition )
                        {
                            callback.apply();

                            window.clearTimeout( window[ "once" ] );
                        } else {
                            window[ "once" ] = window.setTimeout( arguments.callee, duration * 1000 );
                        }
                    }, duration * 1000 );
                }
            开发者_JAVA技巧});

            $.once(testMe == 2, 5, function() {
                alert("Match!");
            });

It looks like when $.once() is being called, the first parameter is then evaluated and only it's value at this time is sent to the condition parameter. The only way I found is to send it as a string:

$.once("testMe == 2" ... and use if ( eval( condition ) )

Is there another way withing the use of eval ?

Thank you.

Edit: here is the a final version of the plugin:

            var testOne = 1,
                testTwo = 1;

            $.extend({
                once : function( name, conditionFn, duration, callback) {
                    if ( typeof duration ==  "function" )
                    {
                        callback = duration;
                        duration = 5;
                    }

                    window[ "once" + name ] = window.setInterval(function() {
                        if ( conditionFn() )
                        {
                            callback();

                            window.clearInterval( window[ "once" + name ] );
                        }
                    }, duration * 1000 );
                }
            });


            //Examples
            $.once("testOne", function() {
                return testOne == 2
            }, 2, function() {
                alert("testOne == 1");
            });

            $.once("testTwo", function() {
                return testTwo == 2
            }, 2, function() {
                alert("testTwo == 1");
            });


You are correct; the parameters are evaluated and then passed. I would not recommend using eval unless you really know what you're doing, and there's a compelling reason to do so.

Instead, pass a predicate (a function which returns a boolean) to your plugin. Every time you want to do the check, invoke the function:

var testMe = 1;

$.extend({
    once : function(predicate, duration, callback) {
        window.once = window.setInterval(function() {
            if (predicate()) {
                window.clearInterval(window.once);
                callback();
            }
        }, duration * 1000);
    }
});

$.once(function () { return testMe == 2; }, 5, function() {
    alert("Match!");
});

N.B. I replaced your repeated setTimeout calls with a self-cancelling setInterval(). Also, you were invoking the callback with callback.apply(), but there is no reason to do this. You can directly call it with (), as the above code does.


Send a function that returns the result of the comparison:

var testMe = 1;

$.extend({
                    // receive the function
    once : function( conditionFn, duration, callback) {
        window[ "once" ] = window.setTimeout(function() {

                // execute the function
            if ( conditionFn() )
            {
                callback.apply();

                window.clearTimeout( window[ "once" ] );
            } else {
                window[ "once" ] = window.setTimeout( arguments.callee, duration * 1000 );
            }
        }, duration * 1000 );
    }
});
        // send a function
$.once(function(){return testMe == 2;}, 5, function() {
    alert("Match!");
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜