2015-11-04 86 views
1

请协助。等待使用settimeout在javascript中重新运行之前完成的函数

我需要wait完成一个操作,然后在javascript中再次执行它。这些操作可能会在不同的时间运行。不是一次全部。由于它们同时执行,所以我一次运行2个操作时遇到问题。

输出应使用settimeout将文本附加到“textarea”中。它需要等待完成,然后开始在调用“arrayofrandomtext”数组的随机索引时键入下一个文本。后来上了“ProcessText(someint)”可能仍然是基于击键等

  • 现有文本称为必须附加在0没有更换,而不是附加 即世界您好。别的东西....

var index=0; 
 
var arrayofrandomtext = ["Hello World","something else", "other stuff"]; 
 
    
 
    function ProcessText(someint){ 
 
    
 
    //These may run together 
 
    next_letter(arrayofrandomtext[someint]); 
 
    //wait to complete and rerun it with other text 
 
    next_letter(arrayofrandomtext[someint]); 
 

 

 
    //later on if the user hits a key this may run only 
 
    next_letter(arrayofrandomtext[someint]); 
 
} 
 

 
function next_letter(text){ 
 

 
    if (index <= text.length) { 
 
    someControl.value = text.substr(0, index++); 
 
    setTimeout(function() { next_letter(text); }, 50); 
 

 
} 
 
}

+0

这是什么'someControl.value'。 –

+0

input,textarea ... – user2185210

回答

1

尝试创建文本值的数组,使用Array.prototype.slice()创建文本值的初始阵列的复印件; Array.prototype.shift()设置next_letter的文本参数;如果阵列inital调用next_letter后有.length,递归调用ProcessText

var arr = ["Hello...", "Some other text"], 
 
    copy = arr.slice(), 
 
    button = document.querySelector("input") 
 
    someControl = document.querySelector("textarea"), 
 
    index = 0; 
 

 
function ProcessText() { 
 
    next_letter(copy.shift()) 
 
} 
 

 
function next_letter(text) { 
 

 
    if (index <= text.length) { 
 
    someControl.value = text.substr(0, index++); 
 
    setTimeout(function() { 
 
     next_letter(text); 
 
    }, 50); 
 
    } else { 
 
    index = 0; 
 
    if (!!copy.length) { 
 
     ProcessText() 
 
    } else { 
 
     copy = arr.slice(); 
 
    } 
 
    } 
 

 
} 
 

 
button.onclick = ProcessText;
<input type="button" value="click" /><br /> 
 
<textarea></textarea>

1

首先,你已经做到了这一点 - 但我想示范工作版本。你可以编写一个递归函数,它在完成后调用settimeout。例如,给定一个函数来注销字符串的每个字母。

var log = function(text, index, duration) { 
    console.log(text[index]); 

    if (index < text.length - 1) { 
    setTimeout(function() { 
     log(text, index + 1, duration); 
    }, duration); 
    } 
}; 

log("Hello There", 0, 1000); 
log("Nice to see You", 0, 1000); 

现在当然,如果你运行这个代码,第二个日志函数将不会等待第一个。您可以使用Promises和/或Callbacks来执行异步控制流程。首先修改日志功能以将回调作为参数。

var logCB = function(text, index, duration, cb) { 
    console.log(text[index]); 

    if (index < text.length - 1) { 
    setTimeout(function() { 
     logCB(text, index + 1, duration, cb); 
    }, duration); 
    } else { 
    cb(); //execute callback 
    } 
}; 

现在,如果你传递你的第二个函数(包装在另一个函数中来延迟执行)。作为您的第一个参数,它将在完成后执行。

var cb = function() { 
    logCB("Nice to see you", 0, 1000); 
}; 

logCB("Hello, World!", 0, 1000, cb); 

虽然这可行,但对于多重嵌套可能会变得笨拙。更好的解决方案是使用承诺 - 您只需要将logCB包装在另一个函数中。这里f是一个logCB。

var promiseLog = function(f, text, delay) { 
    return new Promise(function(resolve, reject) { 
    f(text, 0, delay, resolve); 
    }); 
}; 

然后......我们可以把它们链接在一起等待完成..然后。

promiseLog(logCB, "Hello World", 1000) 
.then(function() { 
    return promiseLog(logCB, "Hey There", 1000) 
}); 
相关问题