Почему поток событий ‘keyup’ в Bacon.combineAsArray немедленно завершается?

#javascript #jquery #frp #bacon.js

#javascript #jquery #frp #bacon.js

Вопрос:

Мне нужно создать Bacon.Property файл, который получает либо true или false , если несколько входных данных html содержат их правильный символ. (Все они должны быть правильными, если нет, то свойство должно быть false )

Для достижения этой цели я создал Array поток потоков событий с помощью помощника jquery.bacons asEventStream и использовал bacons combineAsArray для создания потока «allInputsAreCorrect».

И это когда я терплю неудачу. «allInputsAreCorrect» немедленно завершается. И после завершения он один раз вызывает мой onValue обратный вызов (?). Я понял что-то совершенно неправильно, или это лучший способ объединить все эти входные данные в один Property ?

Вот соответствующие части моего кода, я постарался прокомментировать все как можно лучше:

 var phraseCorrect,
    phraseStream = Bacon.combineAsArray((function () {
        // Using jQuery.map to convert inputs
        // into an Array of eventStreams:
        return $('.keyphrase-list input')
            .map(mapFromInputToStream);
    }()));

// This is how I would like to create the Property..
// But the Stream doesnt fire, so this is unimportant for now.
phraseCorrect = phraseStream.toProperty(false);

phraseStream
    .onEnd(function () {
        // This gets called immediately..
        // And I dont get why.
        console.log('End?? Why????');
    });

phraseStream
    .onValue(function (values) {
        // This gets called **once**
        // (right after the onEnd logging.. ???)
        console.log('Gets called once', values);
    });
 

Функция сопоставления, которая создает keyup eventStreams :

 function mapFromInputToStream() {
    var $input = $(this);

    // I commented out some mapping and filtering.
    // But even without `map` and `filter` it doesnt work.
    return $input
        .asEventStream('keyup');
        // .map(someMapping)
        // .filter(someFiltering);
}
 

В этом коде регистрируется следующее:

 End?? Why????
Gets called once [b.fn.b.init[17]]
 

(есть 17 входов)

После этого ввод чего-либо в одном из входных данных html не вызывает никаких обратных вызовов.

Я был бы признателен, если бы кто-нибудь мог дать мне объяснение такого поведения (немедленно завершающийся поток). Но, конечно, любые подсказки о том, как это исправить (с bacon.js ) приветствуются..

Ответ №1:

Добавьте .get() или .toArray() так, чтобы вы передавали Bacon реальный массив, а не объект jQuery (который возвращается с помощью map ). Бэкон ошибочно примет это за константу (поскольку это не instanceof Array так) и вернет свойство ended, constant.

 var phraseCorrect = Bacon.combineAsArray($('.keyphrase-list input')
                                         .map(mapFromInputToStream)
                                         .get());
 

Комментарии:

1. Спасибо! Я не знал, что jQuery.map не возвращает истинные массивы… Во всяком случае, объединенный поток теперь ничего не запускает, также с .get или .toArray … есть какие-нибудь мысли по этому поводу?

2. jQuery.map делает, jQuery.fn.map не делает. Обратите внимание, что phraseCorrect (из моего кода) не является потоком, combineAsArray всегда сразу возвращает свойства. Убедитесь, что ваши слушатели не подключены к phraseStream

3. Я думаю, остальное — это мои проблемы .. 😉 Но вы ответили на мой вопрос, так что я отмечу его как правильный!

4. Ну , все было правильно! Я просто был слишком глуп, чтобы вводить все входные данные.. Еще раз спасибо 🙂