javascript: модуль вызывает функцию в файле, которая требует модуля - PullRequest
0 голосов
/ 19 мая 2019

Я впервые пишу библиотеку js. Библиотека предназначена для выполнения в определенное время функций в файле, который требовал библиотеки. В некотором роде Angular выполняет реализованные пользователем ловушки, такие как $onInit, за исключением того, что в моем случае пользователь может определить произвольное количество функций, которые будут вызываться моей библиотекой. Как я могу это реализовать?

Один из способов, который я имею в виду, - определить метод registerFunction(name, function), который отображает имена функций в реализации. Но может ли пользователь просто дать мне массив имен, и я автоматически зарегистрирую соответствующие функции для них?

1 Ответ

1 голос
/ 19 мая 2019

Если у вас нет особых требований к этому, вашему модулю не нужно знать названия функций, которые ему предоставляются.Когда ваш модуль вызывает эти функции, он будет делать это, используя прямые ссылки на них, а не используя их имена.

Например:

// my-module.js
module.exports = function callMyFunctions( functionList ) {
    functionList.forEach( fn => fn() )
}
// main application

const myFunc1 = () => console.log('Function 1 executing')
const myFunc2 = () => console.log('Function 2 executing')

const moduleThatInvokesMyFunctions = require('./my-module.js')

// instruct the module to invoke my 2 cool functions
moduleThatInvokesMyFunctions([ myFunc1, myFunc2 ])
//> Function 1 executing
//> Function 2 executing

Убедитесь, что вызывающая сторонапредоставляет прямые ссылки на функции для модуля, который модуль затем использует - без заботы или даже , зная , как называются эти функции.(Да, вы можете получить их имена, проверив ссылки на функции, но зачем?)

Если вы хотите получить более подробный ответ или объяснение, это поможет узнать больше о вашей ситуации.На какую среду ориентирована ваша библиотека: браузеры?nodejs?Electron?response-native?


Библиотека предназначена для выполнения в определенное время функций в файле, для которых требуется библиотека

«В определенное время»предлагает мне что-то, что свободно основано на событиях.Таким образом, в зависимости от платформы, на которую вы ориентируетесь, вы можете использовать настоящий EventEmitter.В этом случае вы должны придумать уникальные имена для каждого времени, когда функция должна быть вызвана, и ваш модуль затем экспортирует одноэлементный эмиттер.Затем вызывающие абоненты назначают обработчики событий для каждого из них, о которых они заботятся.Для вызывающих это может выглядеть так:

const lifecycleManager = require('./your-module.js')

lifecycleManager.on( 'boot', myBootHandler )
lifecycleManager.on( 'config-available', myConfigHandler )
// etc.

Более грубый способ справиться с этим - предоставить вызывающим пользователям словарь функций:

const orchestrateJobs = require('./your-module.js')

orchestrateJobs({
    'boot': myBootHandler,
    'config-available': myConfigHandler
})

Если выНе удобно работать с EventEmitters, это может быть привлекательным.Но для того, чтобы идти по этому пути, необходимо подумать о том, как поддерживать другие сценарии, например, вызывающие абоненты, желающие удалить функцию, и поздняя регистрация.


Быстрый эскиз, показывающий, как использовать apply с каждой функцией:

// my-module.js
module.exports = function callMyFunctions( functionList ) {
    functionList.forEach( fn => fn.apply( thisValue, arrayOfArguments ) )
}

Обратите внимание, что этот модуль до сих пор не знает, какие имена назначил вызывающий абонент этим функциям.В рамках этой области каждая подпрограмма имеет прозвище «fn.»

. Я понимаю, что у вас есть неверное представление о том, как работает выполнение, и это заставляет вас верить, что части программы должны знать именадругие части программы.Но это не то, как работает стиль передачи продолжения.


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

// caller

const AlarmClock = require('./your-module.js')

function doRoosterCall( exactTime ) {
    console.log('I am a rooster! Cock-a-doodle-doo!')
}

function soundCarHorn( exactTime ) {
    console.log('Honk! Honk!')
}

AlarmClock.on('sunrise', doRoosterCall)
AlarmClock.on('leave-for-work', soundCarHorn)
// etc

Чтобы сделать это, вы могли бы сделать что-то вроде ...

// your-module.js

const EventEmitter = require('events')

const singletonClock = new EventEmitter()

function checkForEvents() {
    const currentTime = new Date()

    // check for sunrise, which we'll define as 6:00am +/- 10 seconds
    if(nowIs('6:00am', 10 * 1000)) {
        singletonClock.emit('sunrise', currentTime)
    }

    // check for "leave-for-work": 8:30am +/- 1 minute
    if(nowIs('8:30am', 60 * 1000)) {
        singletonClock.emit('leave-for-work', currentTime)
    }
}

setInterval( checkForEvents, 1000 )

module.exports = singletonClock

(nowIs - это какое-то движение рукой по времени-Сравнения. При выполнении работы, подобной cron, вы должны предполагать, что ваша функция heartbeat почти никогда не сработает, когда значение времени является точным соответствием, и поэтому вам нужно что-то для обеспечения «достаточно близких» сравнений. Я не предоставлялimpl, потому что (1) это кажется второстепенной проблемой, и (2) я уверен, что Momentjs, date-fns или какой-то другой пакет предоставляют что-то отличное, поэтому вам не нужно будет реализовывать это самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...