在JavaScript中另一个(异步)函数完成之后执行一个函数 [英] Executing a function after an another (asynchronous) function finishes in JavaScript

查看:85
本文介绍了在JavaScript中另一个(异步)函数完成之后执行一个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请给我一个普通的JS解决方案,因为我是编码和引入库的新手,只会让我更加困惑.

我在程序中有两个功能:changeText包含异步setTimeout函数(可在X秒内淡入和淡出文本)和userNameinput(允许用户输入文本输入,然后在浏览器上显示输入)的异步setTimeout函数.

我遇到的问题是用户名输入正在与changeText函数一起执行.我的目标是先执行changeText函数并完成,然后在紧随其后执行userNameInput(出现文本输入行)./p>

您可以在我的代码中看到,我已经实现了一个回调,以解决此问题.我创建了一个名为welcome的新函数,将changeText和useNameInput函数捆绑在一起,这样,在调用welcome时,它将首先执行changeText,完成后再调用包装在回调函数中的userNameInput.我以某种方式相信,由于changeText函数中的setTimeout函数在Java脚本环境之外的队列中放置了X倍的时间,因此JS看到堆栈中没有任何内容,可以继续执行usernameInput而无需等待.请帮忙!卡住了太久了!提前致谢.

HTML:

 < div id ="h1">你好,< br></div>< div id ="inputDiv"></div> 

CSS:

 #h1 {不透明度:0;过渡:1s;} 

JS:

  function fadeIn(){document.getElementById('h1').style.opacity ='1';}函数fadeOut(){document.getElementById('h1').style.opacity ='0';}var对话= ['你好,','我叫简.','我有一只狗!','你叫什么名字?'];var input = document.createElement("input");input.setAttribute("type","text");input.setAttribute("value",");input.setAttribute("placeholder",输入您的姓名,然后按Enter");input.setAttribute("maxLength","4");input.setAttribute("size","50");var parent = document.getElementById("inputDiv");parent.appendChild(input);parent.style.borderStyle ='固体';parent.style.borderWidth ='0px 0px .5px 0px';parent.style.margin ='自动';函数changeText(){var timer = 0;var fadeOutTimer = 1000;for(让我= 0;我<对话长度;我++){setTimeout(fadeIn,timer);setTimeout(fadeOut,fadeOutTimer);setTimeout(function(){document.getElementById('h1').innerHTML =对话[i];},timer);计时器=(计时器+ 3000)* 1;fadeOutTimer =(fadeOutTimer + 3000)* 1.1;console.log(timer,fadeOutTimer);}}功能welcome(callback){changeText();打回来();}welcome(function(){函数userNameInput(){函数pressEnter(){var userName = input.value;如果(event.keyCode == 13){document.getElementById('h1').innerHTML =很高兴认识您" +" +用户名+!";}}input.addEventListener("keyup",按Enter);}userNameInput();}); 

解决方案

如果我想总结一下,您遇到的问题是以下问题:

您有两个使用setTimeout延迟执行某些代码的函数.由于setTimeout没有阻塞,它将立即"注册setTimeout的回调并继续执行其余功能.

  function a(){setTimeout(function(){console.log('a');},500)}函数b(){setTimeout(function(){console.log('b');},250)}一种();b(); 

在这里,您希望在500毫秒之后获得"a",然后在又250毫秒之后获得"b",但是在250毫秒之后获得"b",而在另外250毫秒之后获得"a".

执行此操作的旧方法是使用这样的回调:

  function a(callback){setTimeout(function(){console.log('a');打回来();},500)}函数b(){setTimeout(function(){console.log('b');},250)}a(b) 

因此,a会调用b本身.

执行此操作的现代方法是使用promises/async/await:

  function a(){返回新的Promise(function(resolve){setTimeout(function(){console.log('a');解决();},500)});}函数b(){返回新的Promise(function(resolve){setTimeout(function(){console.log('b');解决();},250);});} 

然后致电:

  a().then(b).then(function(){/*做其他事情*/}) 

或在异步函数中:

 异步函数main(){等待a();等待b();//做其他事情}主要的() 

Please give me a vanilla JS solution as I am new to coding and introducing libraries would just confuse me more.

I have two functions in the program: changeText contains asynchronous setTimeout functions that fade text in and out at X seconds and userNameinput that allows the user to enter in a text input and then displays the input back on the browser.

The problem I am running into is that the usernameinput is executing along with the changeText function.My goal is to have the changeText function execute first and finish and then have the userNameInput (the text input line appear)execute right after.

As you can see in my code I have implemented a callback in an attempt to solve this issue. I create a new function called welcome to bundle the changeText and useNameInput functions together in such a way that when welcome is invoked it would execute changeText first, finish and then evoke userNameInput packaged in the callback. Somehow I believe that since the setTimeout functions in the changeText functions are put in queue outside of the Javascript environment for a X amount of time, JS is seeing that there is nothing there in the stack and contiunes to execute usernameInput without waiting. Please help! Been stuck for way too long! Thanks in advance.

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();
});

解决方案

If I wanted to summarize, the problem you're running in is the following one:

You have two functions that use setTimeout to execute some code with a delay. As setTimeout is not blocking, it will "instantly" register the callback of setTimeout and continue executing the rest of the function.

function a() {
    setTimeout(function() {
        console.log('a');
    }, 500)
} 

function b() {
    setTimeout(function() {
        console.log('b');
    }, 250)
}

a();
b();

Here you would like to have "a" after 500ms then "b" after another 250ms but you get "b" after 250ms and "a" after another 250ms.

The old way of doing this would be to use a callback like this:

function a(callback) {
    setTimeout(function() {
        console.log('a');
        callback();
    }, 500)
} 

function b() {
    setTimeout(function() {
        console.log('b');
    }, 250)
}

a(b)

Thus, a will call b itself.

A modern way of doing this would be to use 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);
    });
}

and then call:

a().then(b).then(function() {/* do something else */})

or, within an async function:

async function main() {
    await a();
    await b();
    // do something else
}

main()

这篇关于在JavaScript中另一个(异步)函数完成之后执行一个函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆