Node.js — загрузка и выполнение нескольких функций с помощью Promise.all()

Я разрабатываю концепцию «плагинов», в соответствии с которой у меня есть ряд файлов, каждый из которых содержит одну функцию (плагин). Я хотел бы автоматически загружать и выполнять их, используя promise.all().

Проблема: каждая функция плагина не выполняется.

Вот мой пример плагина plugins/example.js:

"use strict";

exports = function() {
    return new Promise(function(resolve, reject) {
        console.log("Plugin running....");
        setTimeout(resolve, 200, 'example plugin succeeded!');
    });
};

Затем из моего app.js я загружаю все плагины с помощью модуля NPM require-all:

const plugins = require('require-all')(__dirname + '/plugins');

Затем я пытаюсь выполнить все как часть моей цепочки обещаний:

return Promise.all([plugins]);

Регистрация из функции не производится. Интересно, когда я регистрирую содержимое plugins, я вижу и пустой объект:

{
    "example": {}
}

Может ли кто-нибудь посоветовать, почему функция примера не вызывается?


person Ben    schedule 01.11.2016    source источник
comment
plugins — это объект с ключами и значениями, представляющими загруженные плагины, а promise.all принимает массив обещаний, две разные вещи.   -  person adeneo    schedule 01.11.2016
comment
На самом деле вы никогда не вызываете экспортированную функцию, верно?   -  person Bergi    schedule 01.11.2016


Ответы (2)


Подключаемый модуль RequireAll возвращает объект, содержащий имя подключаемого модуля в качестве ключа и импорт в качестве значения, поэтому вам придется получить значения, а затем вызвать эти функции для получения промисов, а затем вы будет массив обещаний

const plugins = require('require-all')(__dirname + '/plugins');

var promises  = Object.keys(plugins).map(function(key) {
    return plugins[key]();
});

Promise.all(promises).then(function() {
    // all done
}).catch(function(err) {
    // fail
});
person adeneo    schedule 01.11.2016
comment
Фантастика - спасибо за руководство, действительно очень полезно. - person Ben; 01.11.2016

Одним из способов сделать это будет что-то вроде следующего. Допустим, есть каталог plugins с такими файлами, как pluginA.js, pluginB.js, ..., pluginZ.js. Как вы указали в своем вопросе, экспортируемое значение из этих плагинов всегда является функцией, которая возвращает обещание. Я бы создал plugins/index.js, который экспортировал бы все из этих плагинов, например:

// plugins/index.js
'use strict'

const pluginA = require('./pluginA')
const pluginB = require('./pluginB')
...
const pluginZ = require('./pluginZ')

module.exports = [ pluginA, pluginB, ..., pluginZ ]

Итак, вы можете использовать это следующим образом:

// foo.js
'use strict'

const _ = require('lodash')
const plugins = require('./plugins')

Promise.all(_.map(plugins, (fn) => fn()))
.then((data) => console.log(data))
.catch((err) => console.log(err))
person Srle    schedule 01.11.2016