React Native 同步函数和异步函数之间的区别

ffx8fchx  于 2023-03-03  发布在  React
关注(0)|答案(2)|浏览(185)

我刚开始进行react-native开发,遇到了async函数。有人能用外行的术语解释一下吗?我试着阅读过关于它的文章,但他们都倾向于用一种非常技术化的方式来解释,这有点令人困惑。我用过其他语言,但javaScript不是我的菜。
我的疑虑是:
1.同步函数和异步函数哪个更像普通函数?
1.在阅读这篇文章https://blog.expo.io/react-native-meets-async-functions-3e6f81111173时,他谈到了返回承诺和等待响应。因此,在这篇文章中,什么是承诺,如果我们正在等待响应,它不应该是一个同步函数吗?
1.当然还有同步函数和异步函数的区别

c6ubokkw

c6ubokkw1#

Javascript是一种单线程语言,这意味着处理I/O、套接字和网络等事务的函数通常会在执行时阻塞主线程。为了能够编写并发代码,而不会阻塞执行可能很慢的任务的主线程,JS使用了所谓的事件循环。因此,异步函数只是一个可以被放入队列中的函数,并且稍后可以在不阻塞主线程的情况下检入该函数的结果。
您可以在MDN上找到有关Event Loop的更多信息,并观看Philip Roberts的此演讲

eanckbw9

eanckbw92#

这是一个具有挑战性的主题,当来自其他编程语言。使用您的术语,一个'正常'函数类似于一个同步函数。
我推荐MDN docs for await,阅读该页,然后运行f1示例--我在下面包含了它,并做了一些增强:
1.我在console.log中添加了时间戳,以便计时更加明显
1.我在调用f1()之前和之后添加了console.log语句。
await关键字并不意味着等待(或阻塞)。它拆分执行流,暂停f1函数(大约2秒后恢复),并返回一个Promise,允许异步函数的调用者选择是否等待异步函数的结果。我们打印出对f1()的调用的结果,但是我们选择不等待延迟的结果,并且我们只是继续前进到下一个console.log
在Node.js中运行以下代码:

///////////////////////////////////////////////////////////////////////
// This is just setting up timestamps for console.log
///////////////////////////////////////////////////////////////////////
const oldlog = console.log;

console.log = function () {
  var args = [].slice.call(arguments);
  oldlog.apply(console.log,[getTimestamp()].concat(args));
};

const getTimestamp = () => '[' + (new Date()).toISOString() + ']';

///////////////////////////////////////////////////////////////////////
// Real code starts here
///////////////////////////////////////////////////////////////////////
function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  console.log('enter f1');
  const x = await resolveAfter2Seconds(10);
  console.log('exit f1, x =', x);
  return x;
}

console.log('before f1');
const y = f1();
console.log('after f1, y =', y);

运行时,这将导致类似以下内容:

[2020-03-03T01:48:50.716Z] before f1
[2020-03-03T01:48:50.719Z] enter f1
[2020-03-03T01:48:50.720Z] after f1, y = Promise { <pending> }
[2020-03-03T01:48:52.725Z] exit f1, x = 10

请特别注意,我们看到after f1日志 * 早于 * 我们看到exit f1日志。执行流被拆分,f1()暂停,而f1()的调用方继续。大约2秒后,f1()的执行恢复。
现在,比较一下如果我们用await代替调用f1()的结果会发生什么。注意,因为我们现在使用的是await,所以我们必须将代码 Package 在async中(实际上是异步IIFE),因为await只能在async函数内部使用。

// console.log('before f1');
// const y = f1();
// console.log('after f1, y =', y);

(async () => {
  console.log('before f1');
  const y = await f1();
  console.log('after f1, y =', y);
})();

现在,输出如下所示:

[2020-03-03T02:19:18.122Z] before f1
[2020-03-03T02:19:18.124Z] enter f1
[2020-03-03T02:19:20.130Z] exit f1, x = 10
[2020-03-03T02:19:20.130Z] after f1, y = 10

请注意,现在,由于调用方选择等待调用f1()的结果,我们看到after f1exit f1的日志颠倒了(使用您的术语,按照“正常”顺序),现在f1()的结果是10,而不是挂起的Promise。
所以,这是一个有点棘手的东西,我鼓励更多的阅读和实验来掌握它。它看起来很复杂,但实际上现在编写异步JavaScript代码比在将async/await引入语言之前要简单。

相关问题