前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Javascript 中的异步操作

Javascript 中的异步操作

原创
作者头像
dandelion1990
发布2024-01-05 00:29:10
1600
发布2024-01-05 00:29:10
举报

最近看 JS 代码,对于 Promise 相关写法不是很熟悉,因此梳理了一下相关概念

Javascript 中的函数写法

在异步操作中会用到的回调函数通常使用匿名函数的写法,这里先复习一下 Javascript 中各种函数写法

代码语言:javascript
复制
function hello () {
    return "Hello world!"
}

// with parameters
function hello (name) {
    return "Hello " + name + "!"
}

// 匿名函数
function (name) {
    return "Hello " + name + "!"
}

// Arrow function
hello = () => { // 等价于 hello = function() {
  return "Hello World!";
}

// 省略 `{}` 和 `return`
hello = (name) => "Hello " + name + "!";
hello = (firstName, lastName) => "Hello " + firstName + " " + lastName + "!";
// 只有一个参数时,括号也可以省略
hello = name => "Hello " + name + "!";

P.S.:

  • 函数只能有一个返回值,如果需要返回多个值,可以把它们放到对象或数组中返回

Promise

Promise 的定义如下:A Promise is an object that represents the result of an asynchronous computation

Javascript 中异步执行的过程通过以下方式实现:

  • 函数调用会被放入 Call Stack
  • Promise callback function 会被放入 Microtask Queue
  • setTimeout, setInterval 等异步 web APIs 会被放入 Task Queue
  • Event Loop 会一直检查 call stack,当其为空时会将 microtask queue 中的 callback function 放入 call stack,当 call stack 和 microtask queue 均为空时才会处理 task queue

创建 Promise 对象

代码语言:javascript
复制
let myPromise = new Promise((resolve, reject) => {
  // do something may not get result immediately
  const v = Math.random()
  console.log(v)
  if ( v > 0.5 ) { // some condition
    // case on some condition
    // call resolve callback function and pass result data as argument
    resolve({ data: 'Here is your data!' })
  } else {
    // case on other condition
    // call reject callback function and pass error as argument
    reject(new Error('Network error'))
  }
})
console.log("promise defined")

上述代码在 Promise 对象创建时会立即允许里面代码,在调用 resolve(res)/reject(err) 时会改变 Promise 对象的状态,这时 Promise 会进入成功/失败状态

调用 Promise.thenPromise.catch 会将里面的 callback 函数放入 microtask queue,等待 Promise 进入成功/失败状态后且 同步代码运行完后调用 callback 函数

代码语言:javascript
复制
// code in the Promise block get executed when created
// code in the `then/catch` block wait until the Promise enter resolved/rejected state
myPromise
  .then(result => {
    console.log('Data:', result.data)
  })
  .catch(error => {
  	console.error('Error:', error.message)  
  })

定义异步函数

代码语言:js
复制
function fetchData() {
  return new Promise((resolve, reject) => {
    console.log(Date.now() + ": promise start")
    const v = Math.random()
    if (v > 0.5) {
      resolve({ data: "hello" })
    } else {
      reject(new Error('Network error'))
    }
    console.log(Date.now() + ": promise end")
  })
}

这时 Promise 内部的代码并不是立即执行,而是在调用 fetchData 函数时执行,下面的代码会立即执行 Promise 的内容,并等待 Promise 状态改变后执行传入 then/catch 的回调函数

代码语言:javascript
复制
fetchData()
  .then((res) => {
    console.log(Date.now() + ": promise resolved")
    console.log(res.data)
  })
  .catch((err) => {
    console.log(Date.now() + ": promise rejected")
  })

链式调用:传入 .then(callback1) 的回调函数可以返回值,这个值会作为参数被传到下一个 .then(callback2) 的回调函数

代码语言:javascript
复制
let promise = new Promise((resolve, reject) => {
    resolve(1)
  })
  
promise
.then(res => {
    console.log(res) // 输出 1
    return res + 1
})
.then(res => {
    console.log(res) // 输出 2
    return res + 1
})
.then(res => {
    console.log(res) // 输出 3
    return res + 1
})

如果回调函数返回了一个 Promise 对象,那么下一个 .then(callback) 同样会等待上一个回调函数的执行

代码语言:javascript
复制
promise
  .then(value => {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(value + 1);
      }, 1000);
    });
  })
  .then(value => {
    console.log(value); // 输出 2,但是在 1 秒后
  });

await/async

是 ES7 中引入的新特性,具体用法如下

async function 关键字定义的函数,自动将返回值包装成一个 Promise,如果正常返回就是 resolved 状态,如果有异常则为 rejected 状态

代码语言:javascript
复制
async function asyncSleep(time) {
  setTimeout(() => {
    console.log(Date.now() + ": asyncSleep")
  }, time * 1000)
}
// 等价于
function sleep(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(Date.now() + ": sleep")
    }, time * 1000)
    resolve()
  })
}

await 只能用在用 async 定义的函数内部, 用于暂停执行等待某个 async 函数的返回

代码语言:javascript
复制
function sleep(time) {
  return new Promise((resolve, reject) => { setTimeout(() => {
      console.log(Date.now() + ": sleep")
    }, time * 1000)
    resolve()
  })
}

async function asyncSleep(time) {
  console.log(Date.now() + ": asyncSleep start")
  await sleep(time)
  console.log(Date.now() + ": asyncSleep end")
}

asyncSleep(1)
  .then(() => {
    console.log(Date.now() + ": asyncSleep resolved")
  })

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Javascript 中的函数写法
  • Promise
    • await/async
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档