Лучший способ остановить / отменить каскад обещаний в dart

#javascript #flutter #dart #promise

#javascript #флаттер #dart #обещание

Вопрос:

Я работаю с одной сложной логикой, и мне нужно было остановить ее, если клиент хочет отменить операцию, но я не понимаю, как это сделать в dart

У меня есть это:

 
final steps =  authenticate(login, password)
        .then((_) => checkLicence())
        .then((_) => registerDevice())
        .then((_) => createDatabaseOnServer())
        .then((_) => waitForDatabase())
        .then((_) => downloadDatabase())
        .then((_) => notifyDatabaseDownloaded())


 

И я хочу добавить опцию остановки / отмены.

Я думаю, что более простой способ — добавить один глобальный шаг отмены bool и добавить его во все функции, например if(cancelStep) throw CancelStepException(stepName) , и обработать, если мне нужно выполнить откат, выход из системы и т. Д. Но я хочу знать, есть ли другой способ сделать это.

Я использую CancelableOperation как опцию, но мне придется сохранить currentStep, если я хочу создать некоторую логику отката.

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

1. Поскольку вам вполне может понадобиться конкретный сценарий отката для каждого шага, я бы просто придерживался того, что вы имели в виду ( if (cancelStep) throw... ) . Если вы используете общую отмену (которая подходит всем), вам все равно придется разделить свою логику в зависимости от того, каким был последний успешный шаг, так что вы можете также сделать это на месте.

Ответ №1:

Не уверен насчет Dart, но с расширением JS amp; Promise lib (c-promise2) вы можете сделать следующее (живая демонстрация):

 import CPromise from "c-promise2";

let i = 0;

const dummyStage = () => {
  let index = i  ;
  return () => {
    console.log(`Stage[${index}]`);
    return CPromise.delay(1000);
  };
};

const authenticate = dummyStage();
const checkLicence = dummyStage();
const registerDevice = dummyStage();
const createDatabaseOnServer = dummyStage();
const waitForDatabase = dummyStage();
const downloadDatabase = dummyStage();
const notifyDatabaseDownloaded = dummyStage();

const steps = CPromise.resolve(authenticate("login", "password"))
  .then((_) => checkLicence())
  .then((_) => registerDevice())
  .then((_) => createDatabaseOnServer())
  .then((_) => waitForDatabase())
  .then((_) => downloadDatabase())
  .then((_) => notifyDatabaseDownloaded())
  .then(
    (v) => console.log(`Done: ${v}`),
    (e) => console.warn(`Fail: ${e} at ${e.scope}`)
  );

setTimeout(() => steps.cancel(), 4000);
 

То же самое с генераторами (живая демонстрация):

 const steps = CPromise.from(function* () {
  try {
    yield authenticate("login", "password");
    yield checkLicence();
    yield registerDevice();
    yield createDatabaseOnServer();
    yield waitForDatabase();
    yield downloadDatabase();
    yield notifyDatabaseDownloaded();
  } catch (e) {
    console.log("isCanceledError", CPromise.isCanceledError(e));
    console.warn(`Fail: ${e} at ${e.scope}`);
  }
}).then((v) => console.log(`Done: ${v}`));

setTimeout(() => steps.cancel(), 4000);