Отмена обещания с библиотекой Bluebird - PullRequest
0 голосов
/ 11 мая 2019

Я изучаю эту библиотеку обещаний синей птицы. Я создал очень простое экспресс-приложение с одним файлом и одним маршрутом - GET /test.

По сути, мой сценарий заключается в том, что у меня есть обещание, которое имеет интервал внутри и разрешается после нескольких интервальных "петель". Интервал работает каждые 1 секунду, и после 5 раз я очищаю интервал и разрешаю обещание.

Но прежде чем я разрешу обещание из интервала, у меня есть тайм-аут, который должен отменить это обещание через 3 секунды и, следовательно, остановить интервал.

Мой код:

const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');
const Promise = require('bluebird');

Promise.config({
    warnings: true,
    longStackTraces: true,
    cancellation: true,
    monitoring: true
});

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));

//promise
const foo = () => {
    return new Promise((resolve, reject) => {
        let index = 0;
        const intervalId = setInterval(() => {
            index++;
            console.log('in interval, index: ', index);
            if(index === 5) {
                clearInterval(intervalId);
                resolve();
            }
        }, 1000);
    });
};

//test route here
app.get('/test', async(req, res) => {
    setTimeout(() => {
        foo.cancel();
    }, 3000);
    try {
        await foo();    
    } catch (e) {
        console.error(e);
    }
    res.send('Completed');
});

app.listen(5000, () => {
    console.log('Listen on port: ', 5000)
});

Итак, сначала мне требуются пакеты экспресс и узлов, затем я устанавливаю конфигурацию bluebird, как они предлагают здесь (потому что отмена по умолчанию отключена).

Тогда у меня есть функция foo, внутри которой есть обещание синей птицы. Есть такая логика с интервалом, о котором я упоминал ранее - порядковый номер увеличивается, а когда он равен 5, интервал в конечном итоге разрешит обещание.

Но до этого в моем маршруте /test у меня есть тайм-аут, который должен отменить это обещание через 3 секунды.

Итак, ожидаемый результат:

в интервале, индекс: 1

в интервале, индекс: 2

в интервале, индекс: 3

Завершена

но на самом деле это не работает и выдает ошибку, что не знает, что такое метод отмены:

C: \ Users \ Admin \ Documents \ cancellationPromise \ bluebirdp \ server.js: 35

   foo.cancel();

       ^

TypeError: foo.cancel не является функцией

EDIT Я изменил свой /test маршрут на этот:

app.get('/test', async(req, res) => {
    let searchPromise = Promise.resolve();
    searchPromise = foo()
        .then(function() {
            console.log('not canceled')
        })
        .catch(function(e) {
            console.log(e);
        })
        .finally(function() {
            if (!searchPromise.isCancelled()) {}
        });

    setTimeout(() => {
        searchPromise.cancel();
    }, 3000);

    res.send('Completed');
});

Так что теперь я звоню "Отмена по возвращенному обещанию" Теперь поведение таково, что он дает ответ через 55 мс, а затем console.log каждую секунду, не останавливаясь на 3:

enter image description here

Возможно ли с помощью bluebird отменить обещание, включая циклы, интервалы и другие вложенные обещания в нем?

1 Ответ

3 голосов
/ 11 мая 2019

Вы отменяете Обещание, но никогда не очищаете интервал. Эти две вещи не связаны должным образом в вашем коде. Это должно выглядеть так:

const foo = () => {
  return new Promise((resolve, reject, onCancel) => {
    let index = 0;
    const intervalId = setInterval(() => {
      index++;
      console.log('in interval, index: ', index);
      if(index === 5) {
        clearInterval(intervalId);
        resolve();
      }
    }, 1000);
    onCancel(() => {
      clearInterval(intervalId);
    });
  });
};
...