1

It seems like require calls are executed asynchronously, allowing program flow to continue around them. This is problematic when I'm trying to use a value set within a require call as a return value. For instance:

main.js:

$(document).ready(function() {
    requirejs.config({
        baseUrl: 'js'
    });

    requirejs(['other1'], function(other1) {
        console.log(other1.test()); //logs out 'firstValue', where I would expect 'secondValue'
    }
});

other1.js

function test() {
    var returnValue = 'firstValue'; //this is what is actually returned, despite the reassignment below...
    requirejs(['other2'], function(other2) {
        other2.doSomething();
        returnValue = 'secondValue'; //this is what I really want returned
    })
    return returnValue;
}

if(typeof module != 'undefined') {
    module.exports.test = test;
}

if(typeof define != 'undefined') {
    define({
        'test':test
    });
}

How can I set a return value for a function from inside a require block?

scubbo
  • 4,969
  • 7
  • 40
  • 71
  • 1
    async functions don't have returns... – dandavis Nov 07 '13 at 21:16
  • 1
    The whole point of require.js is to load your dependencies asynchronously, then launch your function once the dependencies are resolved. _Of course_ require calls run asynchronously, that's the _whole point_ of the library. – Mike Edwards Nov 07 '13 at 21:27

2 Answers2

4

Yes, require calls are executed asynchronously. So your example won't work, because

function test() {
    var returnValue = 'firstValue'; 
    requirejs(['other2'], function(other2) { // <-- ASYNC CALL
        other2.doSomething();
        returnValue = 'secondValue'; 
    })

    return returnValue; // <-- RETURNS FIRST! ('firstValue')
}

The only thing you need to do in your example is:

main.js

requirejs.config({
  baseUrl: 'js'
});

requirejs(['other1'], function(other1) {
  console.log(other1.test())
});

js/other2.js

// No dependencies
define(function() {
   return {
     doSomething: function() {
       return 'secondValue';
     }
   };
});

js/other1.js

// Dependency to other2.js
define(['other2'], function(other2) {
   return {
     test: function() {
        return other2.doSomething();
     }
   };
});

See complete example here: http://plnkr.co/edit/hRjX4k?p=preview

nekman
  • 1,919
  • 2
  • 15
  • 26
  • Hey - thanks for the response! This is interesting - that looks to me like there are two ways of declaring a dependency of "foo" on "bar", either you can write (in foo.js) "requirejs(['bar'], function(bar) {...})" or "define(['bar'], function(bar) {...}", and the latter returns synchronously - is that accurate? I'll have a read around, thank you! – scubbo Nov 08 '13 at 11:25
1

It looks like before other1 returns, you want other2 to be present, and you want to call a method on other2 which will affect what you return for other1.

I think you'll want to-rethink your dependencies. other2 appears to be a dependency of other1; it needs to be defined as such:

//in other1.js
define('other1', ['other2'], function(other2){
    //other2 is now loaded
    other2.doSomething();

    //return whatever you want for `other1`
});
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • I hadn't seen a declaration of dependencies in "define" before. I'll have a read up on that, thank you! – scubbo Nov 08 '13 at 11:26