我需要使用多个参数多次调用一个函数。我希望在上一次调用的超时完成后调用它。我尝试了以下方法,但它似乎没有正常工作。 (Here's the JSFiddle)。
现在它只在第一次通话后等待。我知道这不是正确的方法,但我找不到任何正确显示如何做的例子。我还需要将其转换为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>
函数call()仅用于表示目的。参数可以有任何值,函数myFunction()可以随时随地调用。
答案 0 :(得分:3)
由于这个问题用typescript
标记,我会认为在Typescript中写这个是一个选项。
您可以使用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!");
}
注意:如果您不想要打字稿,babel也支持async/await
,但您仍需要转发器。
注意要使用es5
为async/await
进行编译,如果环境中没有承诺,则需要Priomise
库,并且您可以使用流动的tconfig.json:
"compilerOptions": {
"target": "es5",
"lib": [
"es5",
"es2015.promise",
"dom"
]
}
纯js方法可以使用onDone
回调来通知调用者该函数何时真正完成。最好直接在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);
}
答案 1 :(得分:2)
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>
答案 2 :(得分:0)
尝试这种模式
function callMe(yourParam){
//you can conditionly modify your param
//if (somecondition)
// newParam=yourPram ...
setTimeout(()=>callMe(newParam),1000)
}
答案 3 :(得分:0)
实际上,执行它并不是一个好方法,但在这种情况下,你不能连续调用myFunction
函数,因为setTimeout
运行异步并且不阻塞线程。所以,像这样修改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);
}
Call函数看起来像;
function call(){
myFunction('normal1','heading1','message1'); //Just call first function in the beginning
}