哨笛买c调还是d调:如何知道Javascript回调是同步还是异步

关于哨笛买c调还是d调的问题,在synchronous and asynchronous callbacks in javascript中经常遇到, 嗨!我正在学习回调,我知道回调可以是同步的或异步的。

嗨!我正在学习回调,我知道回调可以是同步的或异步的。

我在https://www.w3schools.com/jquery/jquery_callback.asp上阅读回调,并且很困惑。

有这样的代码:

$("on").click(function(){
    $("p").hide("slow", function(){
        alert("The paragraph is now hidden");
    });
}); 

我可以检查是否有办法知道上面的回调是同步还是异步?

我猜它是上面的 Synchronous,因为它必须等到“慢”动画结束后才会出现警报。默认情况下,在 Javascript 或 Node.js 中,所有回调都是同步的,除非你做类似 setTimeOut 或 process.nextTick?

10

您这里有几个问题,所以我将尝试一一回答:

默认情况下,在 Javascript 或 Node.js 中,所有回调都是同步的,除非您执行 setTimeOut 或 process.nextTick 之类的操作?

在浏览器中,您可以将此作为经验法则:只有setTimeoutsetInterval,请求和事件是异步的。其他内置回调(如Array.prototype.map)是同步的。

在 Node.js 上,它更复杂:例如,您可以执行文件读取synchronouslyasynchronously。然后,您只需要知道回调本质上是异步的。

我可以检查是否有办法知道上面的回调是同步还是异步?

Unfotunately 没有检查您正在调用的方法 / 函数的源代码,您无法知道它是同步还是异步。

我猜它是同步的,因为它必须等到“慢”动画结束之前,警报出现。

没错。你可以从jQuery's documentation for .hide method找到这个:

complete
类型:Function()
动画完成后调用的函数,每个匹配的元素调用一次。

3

回调是一个函数,一旦异步进程完成,它就会被执行。假设我们有一个包含以下数据的对象person

var person = {
 id: 1034
 name: 'Julio',
 age: 23,
 moneyInBank: 0
}

我们想获得这个人的moneyInBank,但我们在本地环境中无法访问该信息。我们需要从另一台服务器的数据库中获取它,这可能需要一段时间,具体取决于 Internet 连接,优化等。

getMoneyInBank(person.id, callback)将遍历该过程并获取所需的信息。如果我们要在没有回调的情况下运行下一个脚本。

getMoneyInBank(person.id);
console.log(person.money);

我们将在输出中得到 0,因为getMoneyInBank在执行日志时尚未完成。如果我们想确保我们将打印有意义的信息,我们需要将代码更改为这样。

getMoneyInBank(persion.id, function(){
  console.log(person.money);
});

使用回调,只有当getMoneyInBank完成时才会调用日志。

2

您可以轻松检查:

function isSync(func, ...args){
 var isSync = false;
 const res = func(...args, r => isSync = true);
 if(res instanceof Promise) res.then(r => isSync = true);
 return isSync;
}
console.log( isSync([].map.bind([])) );
1

简短答案:您需要检查调用方并查找异步操作。

长答案:

回调是一种简单的模式,通过它将函数作为参数传递给更高阶的函数,并将其回调或进一步向下调用。

let mySynchronousFunction = () => 'Hello';
let myHigherOrderFunction = aFunc => {
    return (aFunc() || 'Goodbye') + ' world!';
};

一旦有一个 I / O 操作会阻塞主线程,它将“分支”并继续执行。

如果我们继续前面的示例,我们将观察到以下行为:

let myAsyncFunction = () => {
    return http.get('http://some.document')
       .then(response => console.log(response)
    );
};
myHigherOrderFunction(mySynchronousFunction); // 'Hello world!'
myHigherOrderFunction(myAsyncFunction); // 'Goodbye world!'

这里发生的事情是,主线程一直持续到它不得不等待 I / O,而不是在那里阻塞,它转到下一条指令,并注意到当 I / O 操作不再被阻塞时它需要去的点。

所以在我们的代码中评估的下一个表达式是:

return expression

但是我们的表达式分支出来,因此它返回 undefined。

return undefined

这意味着我们的高阶函数传递了一个异步函数,当它调用 aFunc () 时得到了undefined

一旦 I / O 完成,主线程返回到它离开的地方,这是传递给 Promise 处理程序然后的函数。此时,执行线程已经分支出来,并与主“线程”分开。

现在为您的问题

当调用它的高阶函数同步调用它时,回调将是同步的。相反,如果在异步操作的执行分支的上下文中调用它,它将是异步的。

这意味着您需要检查您传递回调的高阶函数正在做什么,并查找异步操作。

在您的问题的上下文中,让我们检查以下代码(HOF = 高阶函数):

let mySynchronousHOC = aFunc => aFunc('Hello world!');
let myAsyncHOC = aFunc => {
    http.get('http://hello.com')
        .then(response => aFunc('Goodbye world!')
    );
};
myAsyncHOC(msg => {
    console.log(msg);
});
mySynchronousHOC(msg => {
   console.log(msg);
});

其结果将是:

'Hello world'
'Goodbye world'

这里我们知道 myAsyncHOC 是异步的,因为它执行 I / O 操作。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(487)
今日cba推荐:@不推荐与@不推荐(deprecated java)
上一篇
Web是什么专业:模板的隐式专业化是什么意思
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(80条)