简体   繁体   中英

How to call a function by name within a setInterval/setTimeout function?

function loadDate() 
{
    $.ajax({
        type : "POST",
        url : "/ajax/date",
        data : "text",
        success : function(response) 
        {
            $('#dateSection').html(response);
        },
        error : function(e) 
        {
            alert('Ajax Request Failed: ' + e);
        }
    });
}

function loadPoop() 
{
    if(true)

    $.ajax({
        type : "POST",
        url : "/ajax/poop",
        data : "text",
        success : function(response) 
        {
            $('#poopSection').html(response);
        },
        error : function(e) 
        {
            alert('Ajax Request Failed: ' + e);
        }
    });
}

This is essentially what I'm trying to do but nothing I try works beyond making one call

function ajaxCaller(function_name)
{   
    setInterval(window[function_name], 1000);
    //or
    setInterval(function_name, 1000);
}

html page

<button type="button" onclick="loadDate()">Date Button</button>
<div id="dateSection">Ajax Me Bro!</div>

<button type="button" onclick="ajaxCaller(loadDate())">Poop Button</button>
<div id="poopSection">Ajax Me Bro!</div>

<button type="button" onclick="ajaxCaller(loadPoop())">Ajax Caller Button</button>
<div id="ajaxCallerSection">Ajax Me Bro!</div>

Functions in JavaScript are first-class objects. That means that you can use them the same way you would use any other ordinary variable. If you loose the parentheses in your HTML code:

<button type="button" onclick="ajaxCaller(loadDate)">Poop Button</button>
<div id="poopSection">Ajax Me Bro!</div>

<button type="button" onclick="ajaxCaller(loadPoop)">Ajax Caller Button</button>
<div id="ajaxCallerSection">Ajax Me Bro!</div>

You tell JavaScript not to call the function loadPoop or loadDate , but pass it directly to function ajaxCaller as a variable.

With the brackets () you are first running loadDate , after which you pass the result of loadDate to ajaxCaller . In this case both loadDate and loadPoop return nothing, so ajaxCaller will also recieve nothing, and no timeout gets set.

Samw's answer is correct - but I want to try and elaborate a bit on the matter.

In your code you're passing the return value of loadPoop() and loadDate() as a parameter to ajaxCaller(). Basically - first loadPoop() gets called, and then the value it returns (which is nothing in your case) gets passed on into ajaxCaller().

In Samw's answer a pointer to the functions loadPoop() and loadDate() is passed as a parameter, allowing you to later call the functions using function_name(). The same thing is happening with setInterval, where you pass a pointer to the function you want to invoke within setInterval as a parameter.

If you think of the parameters not as an object or a value but as addresses then this makes a bit more sense - basically what happens is that the execution of the code "jumps" to the memory address (a variable name is just what we humans call that specific memory address) - and since a function starts executing at that point in memory - it just carries on.

Now this might be a bit of an oversimplification, but hopefully it'll give you a better idea of why this is OK, and why your method didn't work.

Welcome to the world of pointers!

Since you're using jQuery I'd be inclined to rework the code a little bit to take advantage of it. You can separate out the inline code which is a good thing, and you can reduce the number of ajax functions to one by passing in the function parameter.

<button type="button" data-fn="default">Date Button</button>
<div id="dateSection">Ajax Me Bro!</div>

<button type="button" data-fn="date">Poop Button</button>
<div id="poopSection">Ajax Me Bro!</div>

<button type="button" data-fn="poop">Ajax Caller Button</button>
<div id="ajaxCallerSection">Ajax Me Bro!</div>

$(function () {

  function loadAjax(fn) {
    $.ajax({
      type: "POST",
      url: "/ajax/" + fn,
      data: "text",
      success: function (response) {
        $('#' + type + 'Section').html(response);
      },
      error : function (e) {
        alert('Ajax Request Failed: ' + e);
      }
    });
  }
  }

  $('button').click(function () {
    var fn = $(this).data('fn');
    switch (fn) {
      case 'date':
        setTimeout(function () {
          loadAjax('date');
        }, 1000);
        break;
      case 'poop':
        setTimeout(function () {
          loadAjax('poop');
        }, 1000);
        break;
      default:
        loadAjax('date');
        break;
    }
  });

});

Declaration :

function ajaxCaller(fn) {   
    setInterval(fn, 1000);
}

Usage :

ajaxCaller(loadDate) // instead of : ajaxCaller(loadDate())
ajaxCaller(loadPoop) // instead of : ajaxCaller(loadPoop())

Don't call fn yourself, let setInterval do this job.

i think the argument can't be a function !! anyway just use following

function ajaxCaller(value)
{
if (value=="loadPoop")


setInterval(function(){loadPoop()},1000);

if (value=="loadPoop")

setInterval(function(){loadDate()},1000);
}

and change arguments to be string

<button type="button" onclick="ajaxCaller("loadDate")">Poop Button</button>
<div id="poopSection">Ajax Me Bro!</div>

<button type="button" onclick="ajaxCaller("loadPoop")">Ajax Caller Button</button>
<div id="ajaxCallerSection">Ajax Me Bro!</div>

i think solution here is more dynamic though: How to execute a JavaScript function when I have its name as a string

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