首页 > 解决方案 > 在飞镖中停止/取消承诺级联的最佳方法

问题描述

我使用一种复杂的逻辑,如果客户想取消操作,我需要停止它,但我不知道如何在飞镖中做到这一点

我有这个:


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


我想添加停止/取消选项。

我认为更简单的方法是添加一个全局bool cancelStep并将其添加到所有函数中,例如if(cancelStep) throw CancelStepException(stepName)我是否必须进行回滚、注销等处理,但我想知道是否还有其他方法可以做到这一点。

我播种 CancelableOperation 就像一个选项,但如果我想制作一些回滚逻辑,我将不得不保留 currentStep。

标签: javascriptflutterdartpromise

解决方案


不确定 Dart,但使用 JS 和 Promise 扩展库(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);

推荐阅读