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