我读过为什么我必须使用“等待”方法来异步运行。如果我不想等到方法完成后再继续呢?和回调总是异步的吗?,并且仍然试图理解回调实际上是异步的。
例如,doThat
需要等待GET
数据才能使用它。正如上面的第二个链接所述,javascript是单线程的。
doThis(doThat);
function doThis(callback) {
$.get('http://some_api/some_resource', function (data) {
callback(data);
});
};
function doThat(data) {
// Do something with data
};
我看到的唯一真正的异步功能是承诺和多个承诺,例如,在动画结束时加载其他数据。我希望帮助更好地理解传统回调实际上是异步的。具体的例子有帮助。
发布于 2016-08-24 05:27:08
例如,我可以在动画结束时加载其他数据。
这正是您可以使用代码所做的事情。请注意,您可以在等待doThat
执行时运行其他代码(实际上,“运行其他代码”会使人感到困惑)。就像你的动画例子一样:
function doThis(callback) {
$.get('http://some_api/some_resource', function (data) {
callback(data);
});
};
function doThat(function (data) {
// Do something with data
});
function doAnotherThing(function (data) {
// Do something with data
});
doThis(doThat);
// without waiting for doThat to run, you can IMMEDIATELY call:
doThis(doAnotherThing);
// without waiting for either doThat or doAnotherThing you
// can output some pretty animations:
setInterval(do_animation,100);
// and without waiting for any of the above you can do anything else:
document.body.innerHTML += 'hello';
请注意,让大多数人感到困惑的是,document.body.innerHTML='hello'
部分在之前运行,而不是上面的任何代码。这意味着回调是异步的,因为它们在数据到达时执行,而不是在调用函数时执行。
注意,并非所有回调都是异步的。例如,Array.prototype.forEach()
是同步的:
document.body.innerHTML += 'before<br>';
['hello','world'].forEach(function(x){
document.body.innerHTML += x;
})
document.body.innerHTML += '<br>after';
决定回调是否异步或同步的是调用它的函数。另见:我知道回调函数异步运行,但是为什么呢?
发布于 2016-08-24 04:56:40
从定义开始:
异步,在计算机程序设计中,是指独立于主程序流程的事件的发生以及处理这些事件的方法。这些可能是“外部”事件,例如信号的到达,或程序在执行过程中同时发生的行为,而程序没有阻塞以等待结果。
- Davies,Alex (2012年)。C# 5.0中的异步,通过异步(计算机编程)上的维基百科
对于JavaScript,它的工作方式如下(简化):有一个任务队列等待主线程(也是唯一的)执行。加载脚本时,它是放置在此队列上的任务。任务一直运行到退出为止,没有其他任务可以中断它。但是,任务可能导致将其他任务放在队列中。当一个任务完成时,队列上的下一个任务将启动。如果队列为空,则会立即执行随后进入队列的第一个任务。
任务进入队列的主要方式,除了是解析和执行脚本的主要任务之外:触发事件将将为该事件注册的处理程序放在任务队列中,并且到达setTimeout
或setInterval
计划的时间将关联的任务放置在任务队列中。
在JavaScript上下文中,在同一任务(“主程序流”)内执行的所有内容都被称为同步。在未来任务中执行的所有内容都称为异步。另一种判断方法是--如果下一条语句在回调之前执行,那么它是异步的;如果下一条语句在回调之后执行,则它是同步的。
$.get(opts, callback)
是一个异步调用,因为执行函数callback
的任务在由onreadystatechange
事件触发时将放在任务队列中。如果后面有一条语句,它将首先执行;只有在该任务完成后,由于AJAX调用的更新而进入任务队列的任务才有机会运行。
相反,$.each(collection, callback)
是一个同步调用,因为callback
将直接从each
函数调用,而不退出当前任务,并且不会生成任何附加任务(当然,callback
本身不会生成额外的任务)。下一条语句必须等到each
完成对collection
的每个元素的迭代。
请注意,承诺只是这个机制的包装器。所有你能做的承诺,你可以做,没有他们,只是代码将不会那么漂亮和易读。
https://stackoverflow.com/questions/39114320
复制相似问题