如何从外部函数访问数组?

我是新来的asynchronous编程

function loadPlugin(plugins, callback) { let tests = [[], [], []]; plugins.forEach((plugin) => { f.isPlugin(plugin, (exists) => { if (exists) { if (!f.pluginIsLoaded(plugin)) { tests[0].push(plugin); f.loadPlugin(plugin); } else { tests[1].push(plugin); } } else { tests[2].push(plugin); } }); console.log(tests); }); return tests; } 

 module.exports.isPlugin = (plugin , callback) => { fs.access(`./plugins/${plugin}`, fs.constants.F_OK, (err) => { callback(!err); }); }; 

里面f.isPlugin(plugin, (exists) => { }); 我把plugin插入到tests数组中,我从外部函数console.log(tests)它显示tests数组是一个包含3个空数组的数组。

有什么办法可以保留f.isPlugin(plugin, (exists) => { });内的东西f.isPlugin(plugin, (exists) => { }); 所以我可以从外部函数访问它?

您可以从callback模式切换到承诺,并使用Promise.all等待所有插件检查完成:

 module.exports.isPlugin = plugin => new Promise( resolve => fs.access(`./plugins/${plugin}`, fs.constants.F_OK, err => resolve(!err)) ); function loadPlugin(plugins) { let tests = [[], [], []]; let promises = plugins.map( plugin => f.isPlugin(plugin).then( exists => { let status = !exists ? 2 : +f.pluginIsLoaded(plugin); if (!status) f.loadPlugin(plugin); tests[status].push(plugin); }) ); // Turn the array of promises into one promise, // which provides the tests array when it resolves: return Promise.all(promises).then( _ => tests ); } 

所以你可以这样称呼它:

 loadPlugin(plugins).then( tests => console.log(tests) ); 

您可以使用Promises和asynchronous函数 。

首先,更改isPlugin函数以返回一个Promise

 module.exports.isPlugin = plugin => new Promise(resolve => fs.access(`./plugins/${plugin}`, fs.constants.F_OK, err => resolve(!err)) ); 

然后将loadPlugin函数更改为asynchronous函数:

 async function loadPlugin(plugins) { let tests = [[], [], []]; for (const plugin of plugins) { const exists = await f.isPlugin(plugin); if (exists) { if (!f.pluginIsLoaded(plugin)) { tests[0].push(plugin); f.loadPlugin(plugin); } else { tests[1].push(plugin); } } else { tests[2].push(plugin); } } return tests; } 

请注意,Node.js中还不支持asynchronous函数,因此您必须使用Babel来传输代码。

你不能用一个callback函数返回某个东西,你必须调用带有结果的callback函数。 这不是访问数组的问题,在任何有机会被推送之前,数组正在被打印。 如果你喜欢返回(你应该这样做很有道理),我会推荐使用承诺。 在这里阅读承诺。 我只是用callback做了一个回答,但是我意识到每次都不行。 说实话,我不知道如何做callback。 这是Promise的解决scheme。

 function loadPlugin(plugins) { let tests = [[], [], []]; // This maps your array to a promise for each one that resolves when the task is complete let promises = plugins.map((plugin) => { return new Promise((resolve, reject) => { f.isPlugin(plugin, (exists) => { if (exists) { if (!f.pluginIsLoaded(plugin)) { tests[0].push(plugin); f.loadPlugin(plugin); } else { tests[1].push(plugin); } } else { tests[2].push(plugin); } // Tells the promise the task is complete resolve(); }); }); }); // Wait for all of the tasks to complete then return tests return Promise.all(promises).then(() => tests); } 

@ Gothdo的解决scheme是更好的,但我不知道你是否正在使用一个转译器使用asynchronousawait语法。 我会build议这样做,并与他/她的解决scheme。