我试图制作一个后备函数来模仿Promise for ie and whatnot
我有以下代码:
function goPromise(nr){
console.time("promise");
var sum = 0;
var prom = function(){
return new Promise(function(resolve){
sum = sum + nr;
nr = nr-1;
resolve();
});
}
var doThat = function(){
if(nr > 0){
prom().then(function(){
nr = nr - 1;
doThat()
})
}
else {
console.log(sum);
console.timeEnd("promise");
}
}
doThat();
}
function goNormal(nr){
console.time("normal");
var sum = 0;
var x = function(){
if(nr > 0){
sum = sum + nr;
nr = nr -1;
x();
}
else {
console.timeEnd("normal")
}
}
x();
}
goNormal比goPromise工作得更好,更快。直到我给它一个像50.000这样的大数字。在这种情况下,它给了我这个
无论多少次,它有什么可以做到这一点?
我怎样才能在vanilla js中实现它?
答案 0 :(得分:0)
承诺是未来的回调,因此它 NOT 递归。这就像使用window.setTimeout(这将解决你在goNormal实例中的问题)。在承诺的情况下,你已经设置了它,因此“doThat”函数的当前执行实际上终止了。
由于涉及承诺,导致将来回调,您会发现它会变慢。您会发现使用setTimeout也会降低执行计划的速度。
给出的例子是设计的,因为不需要递归,但是,我明白你的观点。您是否正在尝试解决这个问题,还是这个学术问题?
使用setTimeout查看下面的示例代码。
function goNormal(nr){
console.time("normal");
var sum = 0;
var x = function(){
if(nr > 0){
sum = sum + nr;
nr = nr -1;
window.setTimeout(x, 10);
}
else {
console.timeEnd("normal")
}
}
x();
}
答案 1 :(得分:0)
您可以使用requestAnimationFrame
再次调用该函数,并再次以大约60fps的间隔再次调用...并使其停止直至满足某个条件。见简单示例:
function recurring() {
var t1 = performance.now();
if (t1 > 1000) {
console.log("Done!");
} else {
console.log("Still going ... ");
window.requestAnimationFrame(recurring);
}
}
window.requestAnimationFrame(recurring);

答案 2 :(得分:0)
This post提供了两个很好的解决方案,允许您执行递归函数,就像它是一个简单的循环一样。
第一个," Trampoline"方法:
function trampoline(cb) {
while (cb && cb instanceof Function) {
cb = cb();
}
return cb;
};
function goNormalT(nr) {
console.time("normal");
var sum = 0;
var x = function(){
if(nr > 0){
sum = sum + nr;
nr = nr -1;
return x.bind(null, nr);
}
else {
console.timeEnd("normal");
return null;
}
}
return trampoline(x.bind(null));
};
goNormalT(50000);

还有第二个,一个" Tail Call Optimizer":
function tco(f) {
var value;
var active = false;
var accumulated = [];
return function accumulator() {
accumulated.push(arguments);
if (!active) {
active = true;
while (accumulated.length) {
value = f.apply(this, accumulated.shift());
}
active = false;
return value;
}
}
}
function goNormal(nr) {
console.time("normal");
var sum = 0;
var x = tco(function() {
if (nr > 0) {
sum = sum + nr;
nr = nr - 1;
return x();
} else {
console.timeEnd("normal");
return null;
}
});
return x();
};
goNormal(50000);

第二个是第一个方法的更复杂的实现。
如果难以掌握这些工作方式,请务必查看文章以获得深入解释。