确保回调执行最后一次

时间:2017-11-09 17:45:28

标签: javascript

var a = function(callback){
    setTimeout(function(){ console.log("Hello"); }, 1000);
    callback(b);
}
var b = function(){
    console.log("Done");
}
a(b);

我注意到由于javascript是异步的,上面的代码会在“Hello”之前显示“Done”。

但是,我很好奇,对于下面的代码,如果函数JSON.parse花了太长时间来解析字符串,那么在j = JSON.parse(randomString)之前是否会执行回调(j)?传入回调函数的j将为null。 如果是这样,我该如何防止这种情况?

var randomString = '[{"a":1, "b":2, "c":3}]';
var a = function(callback){
    var j;
    j = JSON.parse(randomString);
    callback(j);
}
var b = function(j){
    console.log("Done: " + JSON.stringify(j));
}
a(b);

3 个答案:

答案 0 :(得分:1)

  

但是,我很好奇,对于以下代码,如果函数callback(j)花了太长时间来解析字符串,那么j = JSON.parse(randomString)之前是JSON.parse会执行吗?

没有。 JSON.parse是一个同步函数。

答案 1 :(得分:1)

Javascript 异步。它的缺点是函数之间缺乏区别,并且不同步。

如果您编写的javascript程序如下所示:

function x() {
  return "Hello";
}

function y() {
  return "World";
}

console.log(x());
console.log(y());

您将始终制作" Hello World"在你的控制台中。 setTimeout()是一个异步函数,如果没有阅读有关函数的文档就不清楚了。由于没有明确的Async标记,因此很难知道将执行哪些订单代码。

作为一般规则,setTimeout()和任何ajax调用都是异步的,其余调用是同步的。如果要确保setTimeout()之类的同步功能尝试使用promises,或将所需的回调嵌入到默认的回调事件中。例如:

function a(cb) {
  setTimeout(function() { console.log("Hello, "); cb() }, 1000)
}

function b() {
  console.log("World");
}

a(b);

这将按预期返回Hello, World

答案 2 :(得分:0)

在您的第一个代码段中,您正在使用setTimeOut。我建议在这里阅读更多相关内容: - https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

这将有助于您理解为什么"完成"在" Hello"。

之前显示

第二个代码段行为将与第一个不同。 JS是一种同步语言,使用setTimeout等定时器函数,可以模仿异步行为