How to get a variable returned across multiple fun

2019-01-19 08:07发布

问题:

This question in summary is to figure out how to pass variables between javascript functions without: returning variables, passing parameters between primary functions, using global variables, and forcing function 1 to wait for function 2 to finish. I figured out a jQuery solution and posted in below (in the answers section).


Old Post: I initialize a set of four functions, each calling on each other in a different way. At the end of it, I need the final modified product (an array) returned to the initializing function.

Global variables don't force the initial function to wait. And returning it backwards four times doesn't work either. How do you pass a modified variable back to its initializing function, if you can't return it? Or why isn't it returning?

(the maze starts at initFunctionA, ends at functionD)

classOne = {
  initFunctionA : function() {
    classTwo.functionB(functionD, array);
    // I NEED ACCESS TO ARRAY2 HERE
  },
  functionD : function(data, array) {
    var array2 = // modifications to array
  }
}

{...}

classTwo = {
  functionB : function(callback, array) {
    $.ajax({
      success: function(ret){
        classTwo.functionC(ret, callback, array)
      }
    });
  },
  functionC : function(ret, callback, array) {
     callback(ret.data.x, array);
  }
}

回答1:

Change your callback (at the call site) such that you capture the return value of functionD. Then, change functionD so that it returns array2. I've added this access to the example below as a convenience. (Also, be sure to include semicolons where "required" if you want to make JSLint happy.)

classOne = {
  initFunctionA : function() {
    var self = this;

    classTwo.functionB(function() {
        var array2 = functionD.apply(self, arguments);

        // ACCESS ARRAY2 HERE
    }, array);
  },
  functionD : function(data, array) {
    var array2 = // modifications to array

    return array2;
  }
};

{...}

classTwo = {
  functionB : function(callback, array) {
    $.ajax({
      success: function(ret){
        classTwo.functionC(ret, callback, array)
      }
    });
  },
  functionC : function(ret, callback, array) {
     callback(ret.data.x, array);
  }
};


回答2:

You can't make it work with a pattern like you've written there; it's simply not possible in Javascript because there's no such thing as "waiting". Your ajax code has to take a callback parameter (which you've got, though it's not clear where it comes from or what it does), and that initial function should pass in code to do what you need with the array after the ajax call finishes.



回答3:

I would use an object constructor:

function ClassOne() {
    this.array2 = [];
}

ClassOne.prototype.initFunctionA = function() {
    // ...
}

ClassOne.prototype.functionD = function(data, array) {
    // Can use array2 EX: this.array2
}

var classOne = new ClassOne();


回答4:

This is how I understand your problem: classTwo handles an AJAX call and may modify the result. classOne makes use of classTwo to get some data and needs the resulting data.

If so, how's this:

classOne = {
  initFunctionA : function() {
    var array = ['a','b','c'];
    classTwo.functionB(this.functionD, array);
  },
  functionD : function(data, array) {
    // This function is called when the AJAX returns.
    var array2 = // modifications to array
  }
}

{...}

classTwo = {
  functionB : function(callback, array) {
    $.ajax({
      success: function(ret){
        classTwo.functionC(ret, callback, array)
      }
    });
  },
  functionC : function(ret, callback, array) {
     callback(ret.data.x, array);
  }
}

So classOne.initFunctionA calls classTwo.functionB which sets up an ajax call. When the ajax call completes successfully, classTwo.functionC is called with the result and the initial array. From here, classOne.functionD is called with ret.data.x and the array.



回答5:

Okay! I found a way to pass variables between functions without:

  • making global variables
  • making object properties (Chaos's solution)
  • passing parameters

These three were suggested here as the only ways.

Accessing variables from other functions without using global variables

But, if you you can't pass parameters directly, and you need one function to wait for the other (i.e, can't rely on references), and you're using asynchronous calls to the server in an intermediate function, then your only solution is:

Using jQuery...

Create this object in the DOM (dynamically if you don't want to muddy your markup):

<div id='#domJSHandler" style="display: none;"></div>

Then in the function that must wait:

//Function & Class Set 2
$('#domJSHandler').bind('proceedWithAction', function(event, param1, param2) {
    // action set 2
});

And in the function to be waited on:

//Function & Class Set 1
// action set 1
$('#domJSHandler').triggerHandler('proceedWithAction', [param1, param2]);

Essentially encase the last actions you need to perform in a jQuery bind custom event on an invisible DOM object. Trigger that event from JS with jQuery's triggerHandler. Pass your parameters and voila!

I'm sure SO will give me crap for this (and for narcissistically accepting my own answer) but I think it's pretty brilliant for a uber-newbie and it worked for me.

So :p Stack Overflow (jk You've all saved my ass many times and I love you all :)