我是javascript的新手,我遇到了在上一行完成之前执行一行代码的问题。据我所知,我需要创建一个回调函数,使最后一行等待前一行完成。我的程序接受用户输入并使用异步'帖子'将其发送到网站,然后返回一条消息。当我将以下两行代码放在一起时,我的原始问题出现了:
req.send(JSON.stringify(payload))
event.preventDefault();
preventDefault()不等待send()函数完成。我试过实现一个回调函数,但我也遇到了问题。
function sendReq(callback){
req.send(JSON.stringify(payload), function(){
callback();
});
}
sendReq(function(){
event.preventDefault();
});
我们非常感谢任何建议。这是我的整个代码以防万一。
var apiKey = "appid=fa7d80c48643dfadde2cced1b1be6ca1";
document.addEventListener('DOMContentLoaded', bindButtons);
function bindButtons(){
document.getElementById('dataSubmit').addEventListener('click', function(event){
var req = new XMLHttpRequest();
var payload = {longUrl:null};
payload.longUrl = document.getElementById('inputData').value;
req.open('POST', 'http://httpbin.org/post&' + apiKey, true);
req.setRequestHeader('Content-Type', 'application/json');
var response = JSON.parse(req.responseText);
req.addEventListener('load',function(){
if(req.status >= 200 && req.status < 400){
document.getElementById('outputData').textContent = response.longUrl;
}
else
console.log("Error in network request");
});
function sendReq(callback){
req.send(JSON.stringify(payload), function(){
callback();
});
}
sendReq(function(){
event.preventDefault();
});
});
}
答案 0 :(得分:2)
你误解了回调是如何运作的。查看recurial.com上的这篇文章:Understanding callback functions in Javascript
你不能在JavaScript [*]中“等待” - 由于名为"Run-to-completion" semantics的东西:你的代码总是运行以响应事件(例如“DOMContentLoaded”,“单击“,或XHR的”加载“),在您当前运行的代码完成之前(通常是return
- 从最外层的函数 - 事件处理程序),将不再处理任何事件 - 并且不会处理其他事件处理程序。
长时间运行的JS代码会使网页冻结,这就是为什么要求您首先编写异步请求的原因 - 同步XHR会导致页面冻结,而代码会等待服务器的响应。
为了避免冻结并仍然完成工作,您可以将代码构造为一系列回调:在启动异步请求后,您将从当前函数返回并让系统在收到响应时回拨您。您可以使用响应的唯一时刻是回调,通过回调的定义。
在您的情况下,指示响应可用的回调是load
处理程序。这就是你应该移动var response = JSON.parse(req.responseText);
行的地方。
PS。 preventDefault()
与您的情况完全无关,它不能用于“等待send()函数完成”;它用于处理事件的情况(例如onsubmit
的{{1}}),并且您希望在此事件触发时阻止浏览器默认执行某些操作(在<form>
示例中 - 好 - 提交表格。)
PPS。在弄清楚基础知识并开始编写连续超过2个回调的代码后,查找“promises”。
PPPS。 [*] 忽略这句话,我添加它只是为了准确,因为它只会让你在这个阶段迷惑:你不能在JavaScript中“等待”,除非你写的是{{3和/或使用当前不可用的"generator")。