RxJS takeUntil не отписывается

Проблема заключается в том, что:

cin >> input;

приведет к тому, что плохой бит будет установлен, когда вы попытаетесь прочитать не числовое значение. После этого любая попытка использовать operator>> молча игнорируется.

Итак, способ исправить это - проверить, находится ли поток в хорошем состоянии, а если нет, то сбросить флаги состояния и попробовать и читать снова. Но обратите внимание, что плохой ввод (который вызвал проблему) по-прежнему находится на входе, поэтому вам нужно также убедиться, что вы выбрасываете его.

if (cin >> input)
{
    // It worked (input is now in a good state)
}
else
{
    // input is in a bad state.
    // So first clear the state.
    cin.clear();

    // Now you must get rid of the bad input.
    // Personally I would just ignore the rest of the line
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // now that you have reset the stream you can go back and try and read again.
}

Чтобы предотвратить его застревание (что вызвано установленный неверный бит), считывается в строку, затем используется строковый поток для анализа ввода пользователя. Я также предпочитаю этот метод (для пользовательского интерактивного ввода), поскольку он позволяет упростить сочетание разных стилей чтения (т.е. комбинировать operator>> и std::getline(), как вы можете использовать их в потоке строк).

#include <iostream>
#include <sstream>
#include <string>
// using namespace std;
// Try to stop using this.
// For anything other than a toy program it becomes a problem.

int main(int argc, char *argv[])
{
    int          input;

    std::string  line;
    while(std::getline(std::cin, line))   // read a line at a time for parsing.
    {
        std::stringstream linestream(line);
        if (!(linestream >> input))
        {
             // input was not a number
             // Error message and try again
             continue;
        }
        if ((input < 1) || (input > 3))
        {
             // Error out of range
             // Message and try again
             continue;
        }
        char errorTest;
        if (linestream >> errorTest)
        {
             // There was extra stuff on the same line.
             // ie sobody typed 2x<enter>
             // Error Message;
             continue;
        }

        // it worked perfectly.
        // The value is now in input.
        // So break out of the loop. 
        break;
    }
}
0
задан Sergei Panfilov 11 March 2019 в 13:57
поделиться

2 ответа

Вы звоните onDestroy() еще до создания цепочки с takeUntil.

Когда вы в конце концов позвоните printFoo(), предыдущие выбросы unsubscribe не будут переизданы, а субъект unsubscribe уже завершен, поэтому takeUntil в этом случае никогда не завершит цепочку.

0
ответ дан martin 11 March 2019 в 13:57
поделиться

Поскольку Субъект излучает до подписки printFoo.

После подписки больше нет Тематических излучений.

Вместо этого вы можете использовать BehaviorSubject, поскольку он содержит излучаемые значения (последнее излученное значение):

const unsubscribe = new BehaviorSubject(false);

function printFoo() {
  of('foo')
    .pipe(takeUntil(unsubscribe.pipe(filter(value => !!value)))) // Don't unsub if it's false emitted
    .subscribe(console.log)
}
function onDestroy() {
  unsubscribe2.next(true); // Emit true to cancel subscription
}
0
ответ дан ritaj 11 March 2019 в 13:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: