【JS中的异步-setTimeout/promise/await&async】

什么是异步?为什么我们需要异步?

异步表示一种非阻塞的操作方式。在编程中,同步操作是指程序按照顺序一步一步地执行,每一步都必须等待上一步的完成才能进行下一步。

而异步操作则允许程序在执行某个任务时,在任务完成之前不必等待,而是可以继续执行后续的任务。这样可以提高程序的效率和响应速度。

例子:想象一下你正在下载一个很大的文件。如果使用同步方式,你必须等待整个文件下载完成,然后才能进行其他操作。在这个过程中,你不能做其他事情,就像你必须一直守在电脑面前直到下载完成。

而使用异步方式,你可以发起下载请求后,继续做其他事情,比如继续浏览网页、发送消息等。一旦文件下载完成,你可以得到通知,然后再处理下载好的文件。这样,你可以在下载的同时做其他事情,不必全程等待,这就是异步的特点。

在前端开发中,异步操作常用于处理网络请求、文件读写、定时任务等。通过使用异步操作,可以提高页面的响应速度,提升用户体验,并且允许多个任务并行执行,从而提高程序的效率。

常见的异步方式、回调地狱和优化

常见的实现异步的方式有以下几种:

  1. 回调函数(Callback):回调函数是一种传递给其他函数的函数,用于在异步操作完成后被调用。例如,可以通过给 setTimeout 函数传递一个回调函数来实现延时执行:

例子1:

setTimeout(function() {
  // 在延时后执行的代码
}, 1000);

上面这段代码中的匿名函数,就是回调函数。

例子2:

// 回调函数
function asyncOperation(callback) {
  setTimeout(function() {
    const result = '异步操作的结果';
    callback(result);  // 在异步操作完成后调用回调函数
  }, 1000);
}

function handleResult(result) {
  console.log(result);  // 处理回调函数传递的结果
}

asyncOperation(handleResult);  // 调用异步操作并指定回调函数

什么是回调函数?回调地狱是怎么出现的?

回调函数是一种特殊的函数,它以参数的形式传递给其他函数,并在特定事件或条件发生时被调用执行。
可以将回调函数理解为一种约定,当某个异步操作完成时,系统会调用回调函数来通知操作的结果或执行相应的操作。

  • 在广义上,任何在特定的事件发生或条件满足时被调用的函数都可以称为回调函数。它常用于异步编程中,用于处理异步操作的结果或执行相应的操作。
    回调函数也可以在其他情况下使用。比如,在某些事件发生时调用的函数、作为参数传递给其他函数的函数等等。
  • 在狭义上,回调函数通常指的是在异步编程中使用的一种特定形式的函数。
    • 在传统的 JavaScript 异步编程中,回调函数通常作为参数传递给异步函数,并在异步操作完成后被调用。例如,setTimeout 函数接受一个回调函数作为参数,并在延时结束后调用该函数。
    • 狭义上的回调函数具有以下几个特点:
      1)作为参数传递给其他函数。
      2)在特定事件发生或条件满足时被调用,通常是异步操作完成后。
      3)被调用时,根据约定的参数列表接收相应的数据或错误信息。
      回调函数的定义可以根据具体的上下文和语境而有所不同,但以上是一些常见的特点。
      需要注意的是,在现代 JavaScript 中,随着 Promise、async/await 等异步编程机制的出现,狭义上的回调函数在一定程度上被取代或进一步封装起来。因此,在讨论回调函数时,最好明确上下文和语境,以免产生误解。

回调函数最初被广泛用于处理异步操作,但随着异步操作的复杂性增加,回调地狱(Callback Hell)成为一个普遍存在的问题。回调地狱指的是在嵌套多层回调函数时,代码变得难以理解和维护的情况。

  1. Promise(承诺):Promise 是 ECMAScript 6 引入的一种异步编程的解决方案。它表示一个异步操作最终会返回一个结果或者错误。使用 Promise,可以通过 .then() 方法链式处理异步操作的结果,同时也提供了 .catch() 用于捕捉异常。
const promise = new Promise(function(resolve, reject) {
  // 执行异步操作,根据操作结果调用 resolve 或 reject
});

promise
  .then(function(result) {
    // 处理异步操作成功的结果
  })
  .catch(function(error) {
    // 处理异步操作失败的错误
  });

Promise的来历

为了解决回调地狱的问题,出现了一些处理异步操作的新机制,其中最突出的是 Promise。
Promise 是一种用于处理异步操作的对象。它表示一个异步操作的最终完成(或失败)以及其结果的值。Promise 提供了一种更优雅的方式来处理异步操作,避免了回调地狱的问题。
Promise 通过链式调用的方式,可以在异步操作完成后执行相应的操作,而不需要嵌套多层回调函数。

Promise 是由 JavaScript 社区提出并推广的一种异步编程机制,它受到许多其他编程语言和框架的影响和启发,是一种经过实践验证的可靠的异步编程解决方案。

promise在项目中的使用&封装

微信小程序写同步promise的最简单方法 非常非常非常基础的使用promise的方法。

不过通常在项目中使用 Promise 时,会将其进行封装以简化使用和提高可维护性。

使用promise的地方常常是向后台发起数据请求的时候,下面是一个非常简单的封装例子(基于微信小程序)

function request(url, method, data) {
  return new Promise((resolve, reject) => {
    wx.request({
      url: url,
      method: method,
      data: data,
      success: res => {
        resolve(res.data);
      },
      fail: err => {
        reject(err);
      }
    });
  });
}

// 使用示例
request('https://api.example.com/users', 'GET', {})
  .then(data => {
    console.log('请求成功', data);
  })
  .catch(err => {
    console.error('请求失败', err);
  });

实际项目中写法会更复杂。

  1. async/await:await/async 可以被视为 Promise 的语法糖,它们实际上是基于 Promise 实现的。
    通过在函数前加上 async 关键字,可以使得函数返回一个 Promise。使用 await 可以将 Promise 值的处理暂停,等待 Promise 完成并返回结果。

这样可以以同步的方式编写异步代码。也是实际开发中非常常用的写法。

async function doSomething() {
  try {
    const result = await someAsyncOperation();
    // 处理异步操作成功的结果
  } catch (error) {
    // 处理异步操作失败的错误
  }
}

doSomething();

关于await&async

async是异步的意思,await是async wait的简写。async会返回一个promise对象,await会阻塞后面的代码,等待这个async的promise完成,并将reslove的结果返回出来。
注意:因为await会阻塞代码 所以 await会和async一起使用才可以,不然浏览器会报错

理解await&async,比较详细完整的介绍值得一看。

异步问题在微信小程序中实际使用的一个例子

  1. 定时器(setTimeout、setInterval):定时器可以用来创建延时执行的异步操作。setTimeout 函数用于在一段时间后执行一个函数,而 setInterval 函数则会按照指定的时间间隔周期性地重复执行一个函数。
setTimeout(function() {
  // 在延时后执行的代码
}, 1000);

setInterval(function() {
  // 每隔一段时间执行的代码
}, 1000);

除了上述方式,还有许多其他的实现异步的方法和技术,例如事件监听、Fetch API、Web Workers 等,这些都是根据具体的场景和需求选择的不同方案。

参考

js Promise与async/await用法详解每一步都有非常简单的代码举例子。
微信小程序学习总结(async,await)

你可能感兴趣的:(前端,javascript)