[英]Executing a function after an another (asynchronous) function finishes in JavaScript
请给我一个vanilla JS解决方案,因为我不熟悉编码和介绍库会让我更加困惑。
我在程序中有两个函数:changeText包含异步setTimeout函数,它们在X秒时淡入淡出文本,userNameinput允许用户输入文本输入,然后在浏览器上显示输入。
我遇到的问题是usernameinput与changeText函数一起执行。我的目标是让changeText函数先执行并完成,然后让userNameInput(文本输入行出现)执行。
正如您在我的代码中看到的,我已经实现了一个回调,试图解决这个问题。 我创建了一个名为welcome的新函数,将changeText和useNameInput函数捆绑在一起,这样当调用welcome时,它将首先执行changeText,然后完成,然后唤起回调中打包的userNameInput。 不知怎的,我相信由于changeText函数中的setTimeout函数被放置在Javascript环境之外的队列中一段时间,因此JS看到堆栈中没有任何内容并且在没有等待的情况下继续执行usernameInput。 请帮忙! 被卡住太久了! 提前致谢。
HTML:
<div id="h1">Hello,<br></div>
<div id="inputDiv"></div>
CSS:
#h1{
opacity: 0;
transition: 1s;
}
JS:
function fadeIn() {
document.getElementById('h1').style.opacity = '1';
}
function fadeOut() {
document.getElementById('h1').style.opacity = '0';
}
var dialogue = ['Hello,', 'My name is Jane.', 'I have a dog!', 'What is your name?'];
var input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("value", "");
input.setAttribute("placeholder", "Type your name then press Enter");
input.setAttribute("maxLength", "4");
input.setAttribute("size", "50");
var parent = document.getElementById("inputDiv");
parent.appendChild(input);
parent.style.borderStyle = 'solid';
parent.style.borderWidth = '0px 0px .5px 0px';
parent.style.margin = 'auto';
function changeText() {
var timer = 0;
var fadeOutTimer = 1000;
for (let i = 0; i < dialogue.length; i++) {
setTimeout(fadeIn, timer);
setTimeout(fadeOut, fadeOutTimer);
setTimeout(function () {
document.getElementById('h1').innerHTML = dialogue[i];
}, timer);
timer = (timer + 3000) * 1;
fadeOutTimer = (fadeOutTimer + 3000) * 1.1;
console.log(timer, fadeOutTimer);
}
}
function welcome(callback) {
changeText();
callback();
}
welcome(function () {
function userNameInput() {
function pressEnter() {
var userName = input.value;
if (event.keyCode == 13) {
document.getElementById('h1').innerHTML = "Nice to meet you" +
" " + userName + "!";
}
}
input.addEventListener("keyup", pressEnter);
}
userNameInput();
});
如果我想总结一下,你运行的问题如下:
你有两个函数使用setTimeout来执行一些延迟的代码。 由于setTimeout没有阻塞,它将“立即”注册setTimeout的回调并继续执行函数的其余部分。
function a() {
setTimeout(function() {
console.log('a');
}, 500)
}
function b() {
setTimeout(function() {
console.log('b');
}, 250)
}
a();
b();
在这里你想要在500ms之后获得“a”然后在另外250ms之后获得“b”但是你在250ms之后获得“b”而在另外250ms之后获得“a”。
这样做的旧方法是使用这样的回调:
function a(callback) {
setTimeout(function() {
console.log('a');
callback();
}, 500)
}
function b() {
setTimeout(function() {
console.log('b');
}, 250)
}
a(b)
因此,a将调用b本身。
这样做的一种现代方法是使用promises / async / await:
function a() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('a');
resolve();
}, 500)
});
}
function b() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('b');
resolve();
}, 250);
});
}
然后打电话:
a().then(b).then(function() {/* do something else */})
或者,在异步函数中:
async function main() {
await a();
await b();
// do something else
}
main()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.