[英]How to wait for setTimeout before each function call?
I need to call a function multiple times with multiple parameters. 我需要使用多个参数多次调用一个函数。 I want it to be called after the timeout of the previous call is completed.
我希望在上一次调用的超时完成后调用它。 I've tried the following method but it doesn't seem to be working correctly.
我尝试了以下方法,但它似乎没有正常工作。 ( Here's the JSFiddle ).
( 这是JSFiddle )。
Right now it is only waiting after first call. 现在它只是在第一次通话后等待。 I know it's not the correct way to do this, but I could not find any examples that correctly showed how to do.
我知道这不是正确的方法,但我找不到任何正确显示如何做的例子。 I will also need to convert it to
typescript
, so please consider that while answering. 我还需要将其转换为
typescript
,所以请在回答时考虑一下。
<!DOCTYPE html>
<html>
<body>
<p>Click the button to wait 3 seconds, then alert "Hello".</p>
<button onclick="call()">Call all methods</button>
<script>
var myVar;
function call(){
myFunction('normal1','heading1','message1');
myFunction('normal2','heading2','message2');
myFunction('normal3','heading3','message3');
/*Output should be:
(first time dont wait)
heading1 message1
(then wait for timeout and remove the elements)
heading2 message2
(then wait for timeout and remove the elements)
heading3 message3
*/
}
function myFunction(msgType,heading,message) {
console.log(!!document.getElementById("snackbarParent"),document.getElementById('snackbarParent'));
if(document.getElementById("snackbarParent") == null)
{
alertFunc(msgType,heading,message);
}
else{
setTimeout(function(){
let parent = document.getElementById('snackbarParent');
parent.parentNode.removeChild(parent);
alertFunc(msgType,heading,message);
},3500);
}
}
function alertFunc(msgType,heading,message) {
let div = document.createElement('div');
div.className = 'snackbarParent';
div.id = "snackbarParent";
div.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>';
document.documentElement.appendChild(div);
// Get the snackbar DIV
let x = document.getElementById("snackbar");
// Add the "show" class to DIV
x.className = "show";
setTimeout(function(){
x.className = x.className.replace("show", "");
alert("Should display "+heading+" "+message+" now!");
}, 3000);
}
</script>
</body>
</html>
The function call() is just for representation purposes. 函数call()仅用于表示目的。 The parameters can have any value and the function myFunction() can be called anytime, anywhere.
参数可以具有任何值,并且可以随时随地调用函数myFunction()。
Since this question is marked with typescript
I'm going to asume that writing this in Typescript is an option. 由于这个问题用
typescript
标记,我打算假设在Typescript中写这个是一个选项。
You could use async/await
to easily achieve the effect you want while your code maintains a normal look: 在代码保持正常外观时,您可以使用
async/await
轻松实现所需的效果:
var myVar;
async function call(){
await myFunction('normal1', 'heading1', 'message1');
await myFunction('normal2', 'heading2', 'message2');
await myFunction('normal3', 'heading3', 'message3');
}
function timeout(delay: number) {
return new Promise(r => setTimeout(r, delay));
}
async function myFunction(msgType: string, heading: string, message: string) {
console.log(!!document.getElementById("snackbarParent"), document.getElementById('snackbarParent'));
if (document.getElementById("snackbarParent") == null) {
await alertFunc(msgType, heading, message);
}
else {
await timeout(3500);
let parent = document.getElementById('snackbarParent');
parent.parentNode.removeChild(parent);
await alertFunc(msgType, heading, message);
}
}
async function alertFunc(msgType, heading, message) {
let div = document.createElement('div');
div.className = 'snackbarParent';
div.id = "snackbarParent";
div.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>';
document.documentElement.appendChild(div);
// Get the snackbar DIV
let x = document.getElementById("snackbar");
// Add the "show" class to DIV
x.className = "show";
await timeout(3000);
x.className = x.className.replace("show", "");
alert("Should display " + heading + " " + message + " now!");
}
Note : If you don't want typescript, babel also has support for async/await
but you will still need a transpiler. 注意 :如果你不想要打字稿,babel也支持
async/await
但是你仍然需要一个转换器。
Note To compile for es5
with async/await
you will need a Priomise
library if promises aren't in the environment, and you can use the flowing tconfig.json: 注意要使用
async/await
编译es5
,如果promises不在环境中,则需要Priomise
库,并且可以使用流动的tconfig.json:
"compilerOptions": {
"target": "es5",
"lib": [
"es5",
"es2015.promise",
"dom"
]
}
A pure js approach could use an onDone
callback to have a way to notify the caller of when the function really completed. 纯js方法可以使用
onDone
回调来通知调用者函数何时真正完成。 This is better that to add the code directly in alertFunc
as other answers suggest as that will make alertFunc
less reusable: 这更好的是直接在
alertFunc
添加代码,因为其他答案建议,因为这将使alertFunc
不再可重用:
function call() {
myFunction('normal1', 'heading1', 'message1', function () {
myFunction('normal2', 'heading2', 'message2', function () {
myFunction('normal3', 'heading3', 'message3', function () {
// DOne
});
});
});
}
function myFunction(msgType, heading, message, onDone) {
console.log(!!document.getElementById("snackbarParent"), document.getElementById('snackbarParent'));
if (document.getElementById("snackbarParent") == null) {
alertFunc(msgType, heading, message, onDone);
}
else {
setTimeout(function () {
var parent = document.getElementById('snackbarParent');
parent.parentNode.removeChild(parent);
alertFunc(msgType, heading, message, onDone);
}, 3500);
}
}
function alertFunc(msgType, heading, message, onDone) {
var div = document.createElement('div');
div.className = 'snackbarParent';
div.id = "snackbarParent";
div.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>';
document.documentElement.appendChild(div);
// Get the snackbar DIV
var x = document.getElementById("snackbar");
// Add the "show" class to DIV
x.className = "show";
setTimeout(function () {
x.className = x.className.replace("show", "");
alert("Should display " + heading + " " + message + " now!");
if (onDone)
onDone();
}, 3000);
}
var massages = []; massages[0] = ['normal1','heading1','message1']; massages[1] = ['normal2','heading2','message2']; massages[2] = ['normal3','heading3','message3']; function settime(i){ setTimeout(fn,3000,i) } function fn(i){ var heading = massages[i][1], message = massages[i][2], msgType = massages[i][0]; let x = document.getElementById("snackbar"); x.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>'; alert("Should display "+heading+" "+message+" now!"); if(i<massages.length-1) {i++;settime(i)}; }
<p>Click the button to wait 3 seconds, then alert "Hello".</p> <button onclick="settime(0)">Try it</button> <div id='snackbar'></div>
try this pattern 尝试这种模式
function callMe(yourParam){
//you can conditionly modify your param
//if (somecondition)
// newParam=yourPram ...
setTimeout(()=>callMe(newParam),1000)
}
Actually, it is not nice approach to perform it but in this case, you couldn't call myFunction
function consecutively because setTimeout
runs asynchronous and don't block the thread. 实际上,执行它并不是一个好方法,但在这种情况下,你不能连续调用
myFunction
函数,因为setTimeout
运行异步并且不阻塞线程。 So, modify alertFunc
like this; 所以,像这样修改
alertFunc
;
function alertFunc(msgType,heading,message) {
let div = document.createElement('div');
div.className = 'snackbarParent';
div.id = "snackbarParent";
div.innerHTML = '<div id="snackbar"><b style="color:' + msgType + '"> ' + heading + ' </b>' + message + '</div>';
document.documentElement.appendChild(div);
// Get the snackbar DIV
let x = document.getElementById("snackbar");
// Add the "show" class to DIV
x.className = "show";
setTimeout(function(){
if(msgType == "normal1")
{
myFunction('normal2','heading2','message2');//Call second function after first one completed
}
if(msgType == "normal2")
{
myFunction('normal3','heading3','message3');//Call third function after second one completed
}
x.className = x.className.replace("show", "");
alert("Should display "+heading+" "+message+" now!");
}, 3000);
}
And the Call function looks like; Call函数看起来像;
function call(){
myFunction('normal1','heading1','message1'); //Just call first function in the beginning
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.