admin管理员组

文章数量:1290417

So,I have the following js files:

test_api.js:

var request = require("request")

//I actually have a url here.API call which returns JSON.
var url = "";

request({
    url: url,
    json: true
}, function (error, response, body) {

    if (!error && response.statusCode === 200) {
        module.exports = body;
        console.log(body) // Prints the json response

    }
});

test.js:

var api = require('./test_api.js');
console.log(api);

So,when I run node test.js I get:

console.log(body) // Prints the json response
console.log(api); //Prints an empty object

Any idea why I get an empty object back?

So,I have the following js files:

test_api.js:

var request = require("request")

//I actually have a url here.API call which returns JSON.
var url = "";

request({
    url: url,
    json: true
}, function (error, response, body) {

    if (!error && response.statusCode === 200) {
        module.exports = body;
        console.log(body) // Prints the json response

    }
});

test.js:

var api = require('./test_api.js');
console.log(api);

So,when I run node test.js I get:

console.log(body) // Prints the json response
console.log(api); //Prints an empty object

Any idea why I get an empty object back?

Share Improve this question edited Mar 11, 2017 at 4:42 Felix Kling 817k181 gold badges1.1k silver badges1.2k bronze badges asked Mar 11, 2017 at 4:33 stergsterg 571 gold badge1 silver badge6 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

When you call request(), you pass it a callback function. That callback function is called sometime in the future (that's an asynchronous callback). Meanwhile the rest of your module continues to execute and your module initialize pletes with nothing assigned to module.exports yet.

So, when the caller does:

var api = require('./test_api.js');

The module has finished loading and nothing was assigned to module.exports yet so therefore, it is still an empty object and thus api contains only an empty object.

Then, sometime later, your request() operation finishes and calls its callback. You then assign something to module.exports, but it's too late. The module was already loading and the caller already grabbed the old module.exports before you replaced it.

All network I/O in node.js is asynchronous. This means that the pletion callback is called some indeterminate time in the future and the rest of your Javascript continues to execute. The only place you can process asynchronous results is inside the pletion callback or in some other function that is called from that callback. Or, you can use promises to do that type of work for you.


So, basically you can't return results that were retrieved with asynchronous operations from the loading of a module and you can't assign them to module.exports. So instead, the modern way to design this is to export either a promise or a function that returns a promise and then the caller can use .then() on the promise to get access to the results.

Here would be a modern way to implement what it looks like you're trying to do using a promise.

var request = require("request")

//I actually have a url here.API call which returns JSON.
var url = "";

function requestP(options) {
    return new Promise((resolve, reject) => {
        request(options, (error, response, body) => {
            if (error) {
                reject(error);
            } else if (response.statusCode !== 200) {
                reject(new Error(`Network request returned status code ${response.statusCode}`));
            } else {
                resolve(body);
            }
        });
    });
}

module.exports = requestP({url, json: true});

Then, the caller would use that like this:

let api = require('./test_api.js');
api.then(body => {
    // process body here
}).catch(err => {
    // process err here
});

For a more general discussion of returning asynchronous results, see How do I return the response from an asynchronous call?

You cannot assign module.exports or assign to exports asynchronously. Instead, you should consider exporting a function that accepts a callback and performs the request (caching/reusing the result if needed).

本文标签: javascriptmoduleexports returns an empty objectStack Overflow