Javascript 使用Q动态运行一系列承诺

Javascript 使用Q动态运行一系列承诺,javascript,knockout.js,typescript,promise,q,Javascript,Knockout.js,Typescript,Promise,Q,我正在用breeze和knockout编写一个带有打字脚本的SPA 我想做的是创建一个启动管理器,它可以执行启动站点所需的必要步骤(例如读取配置json、下载odata元数据、初始化breeze元数据存储等等) 我创建了以下内容来表示启动序列中的每个步骤: export enum LauncherProgressStatus { Ready, InProgress, Success, Failed, Aborted } export class Laun

我正在用breeze和knockout编写一个带有打字脚本的SPA

我想做的是创建一个启动管理器,它可以执行启动站点所需的必要步骤(例如读取配置json、下载odata元数据、初始化breeze元数据存储等等)

我创建了以下内容来表示启动序列中的每个步骤:

export enum LauncherProgressStatus {
    Ready,
    InProgress,
    Success,
    Failed,
    Aborted
}

export class LauncherProgressItem {
    public status: KnockoutObservable<LauncherProgressStatus> = ko.observable<LauncherProgressStatus>();
    public description: KnockoutObservable<String> = ko.observable<String>();

    public statusText: KnockoutComputedFunctions<String> = ko.computed<String>(() => {
        return LauncherProgressItem.getStatusText(this.status());

    });

    public start() {
       this.action(this);
    }

    constructor(descriptionText: String,
                public action: (arg: LauncherProgressItem) => Boolean) {
        this.status(LauncherProgressStatus.InProgress);
        this.description(descriptionText);
    }

    public static getStatusText(status: LauncherProgressStatus) : String {
        switch (status) {
            case LauncherProgressStatus.Ready:
                return "Ready";
            case LauncherProgressStatus.InProgress:
                return "In progress";
            case LauncherProgressStatus.Success:
                return "Success";
            case LauncherProgressStatus.Aborted:
                return "Aborted";
            default: 
                return "Failed";
         }
    }
}
现在的问题是:我想利用这个来创建一个使用Q的承诺链

q.fcall(() => item1.action(item1))
    .then(() => item2.action(item2))
    .fail((r) => { console.log("Many whelps, HANDLE IT!") });
但是我想创建一种管理器对象,它不知道需要多少步骤。它将只负责构建一个承诺数组并按顺序执行它们,同时能够检测错误(大概在失败承诺中)并中止序列

管理器将具有某种包含LauncherProgressItem步骤的集合。然后,我希望根据该系列的内容建立一个承诺链

我已经研究了一段时间了,但似乎无法真正了解如何使用Q来实现这一点。我看到了一些示例等,但我并不真正理解它是如何工作的

有人对如何实现这一目标有什么建议吗

更新:我将尝试澄清我试图实现的目标:我的LauncherProgressItem包装了一个lambda函数和一些绑定到视图的状态信息。这就是为什么我要用这些,但这与我正在努力解决的问题无关

让我们假设我有一个包含lambda数组的类。该类有一个方法,该方法将使用Q按顺序运行所有这些lamba,并在出错时中止。我将通过以下代码实现以下目标:

Q.fcall(doSomething).then(doSomethingElse).fail(reportError);

但是,在这种情况下,
doSomething
doSomethingElse
驻留在函数数组中,而不是固定数量的步骤中。这是因为我希望它是可重用的,即能够根据手头的任务在多个场景中运行。因此,我希望避免对要运行的函数链进行硬编码

对不起,我不知道typescript,但我认为上面的评论线程运行得不太好,所以这里是您在纯JS中要求的函数:

function runInSequence (functions) {
    if (!functions || !functions.length) {
        return;
    }

    var nextPromise = Q.fcall(functions[0]);

    functions.slice(1).forEach(function (f) {
        nextPromise = nextPromise.then(f);
    });

    nextPromise.fail(yourErrorHandler);
}

为什么您需要所有这些
LauncherProgressItem
s?仅仅使用承诺来确定操作顺序有什么错?不管怎样,这就是承诺所做的……你可能会发现它很有趣。这篇文章实际上是关于各种“反模式”的罪过,没有一个是你犯的(好吧,没有一个是我们知道的:),但标题“收集混乱”下的第二个“好”模式至少可以帮助你更好地理解这个问题。这种模式的一些轻微调整甚至可以提供一个解决方案。可能是@BenjaminGruenbaum的复制品。我的问题是如何动态地连锁承诺。你问我“为什么不只是使用承诺”,虽然我已经清楚地说“我看到了一些例子,但我真的不明白它是如何工作的。”你也对我投了反对票,因为我不是每天都来这里?周末也一样!干杯我正在类中包装工作项,以便将它们绑定到我的初始屏幕。可能有数百万种方法可以做到这一点,但我在这里征求意见。你为什么不试着建设性地帮助我?@havardhu我试着建设性地帮助你,否决票是促使你着手解决问题的一种方式。对我来说,最简单的事情就是不发表评论,这会使你的问题在几天内自动删除。如果这看起来很严厉,我很抱歉,但那是因为我想帮忙。你能澄清一下你到底想做什么吗?对我来说,从一个不了解我的代码的人的角度来阅读这篇文章是可行的。
function runInSequence (functions) {
    if (!functions || !functions.length) {
        return;
    }

    var nextPromise = Q.fcall(functions[0]);

    functions.slice(1).forEach(function (f) {
        nextPromise = nextPromise.then(f);
    });

    nextPromise.fail(yourErrorHandler);
}