开发者问题收集

javascript 递归类:未定义方法

2016-01-05
1048

我有一个 JavaScript 类,旨在帮助处理承诺。首先,您将函数添加到数组中,然后它执行它们并弹出它们,然后调用自身执行下一个。在数组的末尾,它会解析该承诺。我希望将解析一直传播到递归调用堆栈。这将允许您使用一组简单的命令强制多个异步函数按顺序运行。此外,使用逻辑来修改异步函数的流程。

function Sequencer() {

    this.functionSequence = [];

    this.addFunction = function (func) {
        this.functionSequence.push(func);
    }
    this.getFunctionSequence = function () {
        return functionSequence;
    }
    this.executeAll = function () {
        var functionList = this.functionSequence;
        var deferred = $q.defer();
        if (functionList.length > 0) {
            functionList[0]().then(function (result) {
                if (result) {
                    functionList.splice(0, 1);
                    executeAll().then(function (resultInner) {
                        if (resultInner == true) {
                            deferred.resolve(true);
                        } else {
                            deferred.resolve(false);
                        }
                    });
                } else {
                    functionList = [];
                    deferred.resolve(false);
                }
            });
        } else {
            deferred.resolve(true);
        }
        return deferred.promise;
    }
}

我在此脚本中收到 ReferenceError:'executeAll' 未定义 ,在紧接在拼接之后的递归调用行“executeAll”上

数组中的第一个函数正在执行(我使用模态弹出窗口对其进行测试),当它解析时,它会命中拼接,然后它会在 executeAll 行上抛出错误。我是否错误地定义了该函数?我是否正确地将其调用为递归函数?

1个回答

使用 this.executeAll - 假设 this 是正确的,但事实并非如此,因此您还需要考虑这一点... 在 executeAll 顶部使用 var self = this 之类的东西,然后调用 self.executeAll

this.executeAll = function() {
    var functionList = this.functionSequence;
    var deferred = $q.defer();
    var self = this; // save reference to this
    if (functionList.length > 0) {
        functionList[0]().then(function(result) {
            if (result) {
                functionList.splice(0, 1);
                // need to use self here because "this" is not the "this" we want
                self.executeAll().then(function(resultInner) {
                    if (resultInner == true) {
                        deferred.resolve(true);
                    } else {
                        deferred.resolve(false);
                    }
                });
            } else {
                functionList = [];
                deferred.resolve(false);
            }
        });
    } else {
        deferred.resolve(true);
    }
    return deferred.promise;
};

this 不是您“想要”的 this 的原因在于 this 在 javascript 中的工作方式 - stack exchange 上有很多关于使用 this 的信息 - 我会尽快找到并链接一个好的答案


我提供这个替代代码

this.executeAll = function() {
    return this.functionSequence.reduce(function(promise, item) {
        return promise.then(function(result) {
            if (result) {
                return item();
            }
            else {
                throw "Fail"; // throw so we stop the chain
            }
        });
    }, Promise.resolve(true))
    .then(function(result) {
        this.functionSequence = []; // clear out the added functions
        return true; // fulfilled value is true as per original code
    }.bind(this), function(err) {
        this.functionSequence = []; // clear out the added functions
        if (err == "Fail") {
            return false; // convert the "Fail" to a fullfilled value of false as per original code
        }
        else {
            throw err; // any other error - re-throw the error
        }
    }.bind(this))
};
Jaromanda X
2016-01-05