【问题标题】:Javascript Promises how to do post resolution cleanupJavascript Promises 如何进行解析后清理
【发布时间】:2015-11-24 06:46:09
【问题描述】:

我正在为如何处理这种特殊情况而苦苦挣扎。我知道我可以通过链式回调来解决这个问题,但它似乎几乎是 Promise 的典型代表:

我有一个父方法需要按顺序执行三个异步操作(特别是从用户那里获得确认)。我们称它们为 func1 func2 和 func3。现在我可以让它们中的每一个都返回一个承诺并将它们链接起来,这一切都很好。我遇到的问题是:

func1 需要设置一个状态,等待链的其余部分运行,然后取消设置该状态。

演示伪代码:

function wrapper(){
    func1()
        .then(func2())
        .then(func3());
}
function func1(){
    return new Promise(function(resolve, reject){
        //do some async stuff that itself returns a promise :)
        async1().then(function(value){
            //set some global states based on the value for the duration of this chain
            resolve(); //Note NOT returning value as it's irrelevant to the other functions
            //!!! clean up the global states regardless of future failure or success, but after one of those.
        }, reject); //if async1 rejects, just pass that right up.
    });
}
function func2(){
    //do some logic here to decide which asyn function to call
    if (/*evaluates to */true){
        return async2(); //another async function that returns a promise, yay!
    } else {
        return async2_1(); //also returns a promise.
    }
}
function func3(){
    //do some dom updates to let the user know what's going on
    return Promise.resolve(async3()).then(function(){
        //update the dom to let them know that everything went well.
    });//returns this promise chain as a promise which the other chain will use.
}

我正在努力解决的部分是 func1 中 resolve(); 之后的行。请注意,正如所说的那样,我在 func1 中调用的 async1 确实返回了一个承诺,所以我已经在这里使用了很多承诺。我需要在 func3 返回的承诺解决后进行清理。

理想情况下,这一切都会以某种方式包含在 func1 中,但我也可以使用半全局变量(整个块将被包装在一个更大的函数中)。

【问题讨论】:

  • 你会想看看disposer pattern
  • @Bergi 虽然我理解 disposer 模式的概念,但它要求它包装您的所有其他承诺。在这种情况下,我必须将包装器函数包装在处置器模式中。这绝对不是我想要的,因为我想保持密切。基本上在这种情况下,我需要一种方法来从决心中获得承诺,但不知道该怎么做。
  • 您不必包装包装函数。它只是类似于function wrapper() { func1(value => func2().then(func3)) }。不,resolve 永远不会返回承诺。您必须接受对func1 的回调。
  • 无法确定承诺代码您认为应该等待的“剩余运行时间”。你需要明确。没有办法绕过它(除了一些你不想在这里考虑的魔法)。
  • @Bergi 不幸的是,这真的很烦人和限制。我可以在继续之前传递一个回调并“捕获”它,然后在链的最末端调用该回调......

标签: javascript ecmascript-6 es6-promise


【解决方案1】:

您需要使用disposer pattern(并避免使用Promise constructor antipattern):

function with1(callback) {
    return async1() // do some async stuff that itself returns a promise :)
    .then(function(value) {
        // set some global states based on the value for the duration of this chain
        const result = Promise.resolve(value) // or whatever
        .then(callback);

        return result.then(cleanup, cleanup);
        function cleanup() {
            // clean up the global states regardless of the failure or success of result
            return result;
        }
    });
}

你可以这样使用

function wrapper() {
    with1(() =>
        func2().then(func3) // whatever should run in the altered context
    );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    相关资源
    最近更新 更多