当前位置: 首页 > news >正文

面试手写实现Promise.all

目录
  • 前言
  • 常见面试手写系列
  • Promise.resolve
    • 简要回顾
    • 源码实现
  • Promise.reject
    • 简要回顾
    • 源码实现
  • Promise.all
    • 简要回顾
    • 源码实现
  • Promise.allSettled
    • 简要回顾
    • 源码实现
  • Promise.race
    • 简单回顾
    • 源码实现
  • 结尾

前言

(?﹏?)曾经真实发生在一个朋友身上的真实事件,面试官让他手写一个Promise.all,朋友现场发挥不太好,没有写出来,事后他追问面试官给的模糊评价是基础不够扎实,原理性知识掌握较少... 当然整场面试失利,并不仅仅是这一个题目,肯定还有其他方面的原因。

但是却给我们敲响一个警钟:Promise手写实现、Promise静态方法实现早已经是面试中的高频考题,如果你对其还不甚了解,耽误你10分钟,我们一起干到他懂O(∩_∩)O

常见面试手写系列

最近很想做一件事情,希望可以将前端面试中常见的手写题写成一个系列,尝试将其中涉及到的知识和原理都讲清楚,如果你对这个系列也感兴趣,欢迎一起来学习噢,目前已有66+手写题实现啦!

1. 点击查看日拱一题源码地址(目前已有66+个手写题实现)

2.脚本之家专栏

Promise.resolve

简要回顾

  • Promise.resolve(value) 方法返回一个以给定值解析后的Promise 对象。
  • 如果这个值是一个 promise ,那么将返回这个 promise ;
  • 如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。

这是MDN上的解释,我们挨个看一下

  • Promise.resolve最终结果还是一个Promise,并且与Promise.resolve(该值)传入的值息息相关
  • 传入的参数可以是一个Promise实例,那么该函数执行的结果是直接将实例返回
  • 这里最主要需要理解跟随,可以理解成Promise最终状态就是这个thenable对象输出的值

小例子

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 1. 非Promise对象,非thenable对象

Promise.resolve(1).then(console.log) // 1

// 2. Promise对象成功状态

const p2 = new Promise((resolve) => resolve(2))

Promise.resolve(p2).then(console.log) // 2

// 3. Promise对象失败状态

const p3 = new Promise((_, reject) => reject('err3'))

Promise.resolve(p3).catch(console.error) // err3

// 4. thenable对象

const p4 = {

  then (resolve) {

    setTimeout(() => resolve(4), 1000)

  }

}

Promise.resolve(p4).then(console.log) // 4

// 5. 啥都没传

Promise.resolve().then(console.log) // undefined

源码实现

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

Promise.myResolve = function (value) {

  // 是Promise实例,直接返回即可

  if (value && typeof value === 'object' && (value instanceof Promise)) {

    return value

  }

  // 否则其他情况一律再通过Promise包装一下

  return new Promise((resolve) => {

    resolve(value)

  })

}

// 测试一下,还是用刚才的例子

// 1. 非Promise对象,非thenable对象

Promise.myResolve(1).then(console.log) // 1

// 2. Promise对象成功状态

const p2 = new Promise((resolve) => resolve(2))

Promise.myResolve(p2).then(console.log) // 2

// 3. Promise对象失败状态

const p3 = new Promise((_, reject) => reject('err3'))

Promise.myResolve(p3).catch(console.error) // err3

// 4. thenable对象

const p4 = {

  then (resolve) {

    setTimeout(() => resolve(4), 1000)

  }

}

Promise.myResolve(p4).then(console.log) // 4

// 5. 啥都没传

Promise.myResolve().then(console.log) // undefined

疑问

从源码实现中,并没有看到对于thenable对象的特殊处理呀!其实确实也不需要在Promise.resolve中处理,真实处理的地方应该是在Promise构造函数中,如果你对这块感兴趣,马上就会写Promise的实现篇,期待你的阅读噢。

Promise.reject

简要回顾

Promise.reject() 方法返回一个带有拒绝原因的Promise对象。

?

1

2

3

4

5

6

Promise.reject(new Error('fail'))

  .then(() => console.log('Resolved'),

        (err) => console.log('Rejected', err))

// 输出以下内容       

// Rejected Error: fail

//    at <anonymous>:2:16       

源码实现

reject实现相对简单,只要返回一个新的Promise,并且将结果状态设置为拒绝就可以

?

1

2

3

4

5

6

7

8

9

10

11

Promise.myReject = function (value) {

  return new Promise((_, reject) => {

    reject(value)

  })

}

// 测试一下

Promise.myReject(new Error('fail'))

  .then(() => console.log('Resolved'),

        (err) => console.log('Rejected', err))

// Rejected Error: fail

//    at <anonymous>:9:18

Promise.all

简要回顾

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。这个静态方法应该是面试中最常见的啦

?

1

const p = Promise.all([p1, p2, p3])

最终p的状态由p1、p2、p3决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

const p1 = Promise.resolve(1)

const p2 = new Promise((resolve) => {

  setTimeout(() => resolve(2), 1000)

})

const p3 = new Promise((resolve) => {

  setTimeout(() => resolve(3), 3000)

})

const p4 = Promise.reject('err4')

const p5 = Promise.reject('err5')

// 1. 所有的Promise都成功了

const p11 = Promise.all([ p1, p2, p3 ])

    .then(console.log) // [ 1, 2, 3 ]

      .catch(console.log)

// 2. 有一个Promise失败了

const p12 = Promise.all([ p1, p2, p4 ])

    .then(console.log)

      .catch(console.log) // err4

// 3. 有两个Promise失败了,可以看到最终输出的是err4,第一个失败的返回值

const p13 = Promise.all([ p1, p4, p5 ])

    .then(console.log)

      .catch(console.log) // err4

源码实现

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

Promise.myAll = (promises) => {

  return new Promise((rs, rj) => {

    // 计数器

    let count = 0

    // 存放结果

    let result = []

    const len = promises.length

    if (len === 0) {

      return rs([])

    }

    promises.forEach((p, i) => {

      // 注意有的数组项有可能不是Promise,需要手动转化一下

      Promise.resolve(p).then((res) => {

        count += 1

        // 收集每个Promise的返回值

        result[ i ] = res

        // 当所有的Promise都成功了,那么将返回的Promise结果设置为result

        if (count === len) {

          rs(result)

        }

        // 监听数组项中的Promise catch只要有一个失败,那么我们自己返回的Promise也会失败

      }).catch(rj)

    })

  })

}

// 测试一下

const p1 = Promise.resolve(1)

const p2 = new Promise((resolve) => {

  setTimeout(() => resolve(2), 1000)

})

const p3 = new Promise((resolve) => {

  setTimeout(() => resolve(3), 3000)

})

const p4 = Promise.reject('err4')

const p5 = Promise.reject('err5')

// 1. 所有的Promise都成功了

const p11 = Promise.myAll([ p1, p2, p3 ])

    .then(console.log) // [ 1, 2, 3 ]

      .catch(console.log)

// 2. 有一个Promise失败了

const p12 = Promise.myAll([ p1, p2, p4 ])

    .then(console.log)

      .catch(console.log) // err4

// 3. 有两个Promise失败了,可以看到最终输出的是err4,第一个失败的返回值

const p13 = Promise.myAll([ p1, p4, p5 ])

    .then(console.log)

      .catch(console.log) // err4

// 与原生的Promise.all返回是一致的   

Promise.allSettled

简要回顾

有时候,我们希望等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。显然Promise.all(其只要是一个失败了,结果即进入失败状态)不太适合,所以有了Promise.allSettled

Promise.allSettled()方法接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更,一旦发生状态变更,状态总是fulfilled,不会变成rejected

还是以上面的例子为例, 我们看看与Promise.all有什么不同

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

const p1 = Promise.resolve(1)

const p2 = new Promise((resolve) => {

  setTimeout(() => resolve(2), 1000)

})

const p3 = new Promise((resolve) => {

  setTimeout(() => resolve(3), 3000)

})

const p4 = Promise.reject('err4')

const p5 = Promise.reject('err5')

// 1. 所有的Promise都成功了

const p11 = Promise.allSettled([ p1, p2, p3 ])

    .then((res) => console.log(JSON.stringify(res, null,  2)))

// 输出

/*

[

  {

    "status": "fulfilled",

    "value": 1

  },

  {

    "status": "fulfilled",

    "value": 2

  },

  {

    "status": "fulfilled",

    "value": 3

  }

]

*/

// 2. 有一个Promise失败了

const p12 = Promise.allSettled([ p1, p2, p4 ])

    .then((res) => console.log(JSON.stringify(res, null,  2)))

// 输出

/*

[

  {

    "status": "fulfilled",

    "value": 1

  },

  {

    "status": "fulfilled",

    "value": 2

  },

  {

    "status": "rejected",

    "reason": "err4"

  }

]

*/

// 3. 有两个Promise失败了

const p13 = Promise.allSettled([ p1, p4, p5 ])

    .then((res) => console.log(JSON.stringify(res, null,  2)))

// 输出

/*

[

  {

    "status": "fulfilled",

    "value": 1

  },

  {

    "status": "rejected",

    "reason": "err4"

  },

  {

    "status": "rejected",

    "reason": "err5"

  }

]

*/

可以看到:

  • 不管是全部成功还是有部分失败,最终都会进入Promise.allSettled的.then回调中
  • 最后的返回值中,成功和失败的项都有status属性,成功时值是fulfilled,失败时是rejected
  • 最后的返回值中,成功含有value属性,而失败则是reason属性

源码实现

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

Promise.myAllSettled = (promises) => {

  return new Promise((rs, rj) => {

    let count = 0

    let result = []

    const len = promises.length

    // 数组是空的话,直接返回空数据

    if (len === 0) {

      return rs([])

    }

    promises.forEach((p, i) => {

      Promise.resolve(p).then((res) => {

        count += 1

        // 成功属性设置

        result[ i ] = {

          status: 'fulfilled',

          value: res

        }

        if (count === len) {

          rs(result)

        }

      }).catch((err) => {

        count += 1

        // 失败属性设置

        result[i] = {

          status: 'rejected',

          reason: err

        }

        if (count === len) {

          rs(result)

        }

      })

    })

  })

}

// 测试一下

const p1 = Promise.resolve(1)

const p2 = new Promise((resolve) => {

  setTimeout(() => resolve(2), 1000)

})

const p3 = new Promise((resolve) => {

  setTimeout(() => resolve(3), 3000)

})

const p4 = Promise.reject('err4')

const p5 = Promise.reject('err5')

// 1. 所有的Promise都成功了

const p11 = Promise.myAllSettled([ p1, p2, p3 ])

    .then((res) => console.log(JSON.stringify(res, null,  2)))

// 输出

/*

[

  {

    "status": "fulfilled",

    "value": 1

  },

  {

    "status": "fulfilled",

    "value": 2

  },

  {

    "status": "fulfilled",

    "value": 3

  }

]

*/

// 2. 有一个Promise失败了

const p12 = Promise.myAllSettled([ p1, p2, p4 ])

    .then((res) => console.log(JSON.stringify(res, null,  2)))

// 输出

/*

[

  {

    "status": "fulfilled",

    "value": 1

  },

  {

    "status": "fulfilled",

    "value": 2

  },

  {

    "status": "rejected",

    "reason": "err4"

  }

]

*/

// 3. 有两个Promise失败了

const p13 = Promise.myAllSettled([ p1, p4, p5 ])

    .then((res) => console.log(JSON.stringify(res, null,  2)))

// 输出

/*

[

  {

    "status": "fulfilled",

    "value": 1

  },

  {

    "status": "rejected",

    "reason": "err4"

  },

  {

    "status": "rejected",

    "reason": "err5"

  }

]

*/

Promise.race

简单回顾

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

?

1

const p = Promise.race([p1, p2, p3])

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

?

1

2

3

4

5

6

7

8

9

10

11

12

const p1 = new Promise((resolve, reject) => {

  setTimeout(resolve, 500, 1)

})

const p2 = new Promise((resolve, reject) => {

  setTimeout(resolve, 100, 2)

})

Promise.race([p1, p2]).then((value) => {

  console.log(value) // 2

})

Promise.race([p1, p2, 3]).then((value) => {

  console.log(value) // 3

})

源码实现

聪明的你一定马上知道该怎么实现了,只要了解哪个实例先改变了,那么Promise.race就跟随这个结果,那么就可以写出以下代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Promise.myRace = (promises) => {

  return new Promise((rs, rj) => {

    promises.forEach((p) => {

      // 对p进行一次包装,防止非Promise对象

      // 并且对齐进行监听,将我们自己返回的Promise的resolve,reject传递给p,哪个先改变状态,我们返回的Promise也将会是什么状态

      Promise.resolve(p).then(rs).catch(rj)

    })

  })

}

// 测试一下

const p1 = new Promise((resolve, reject) => {

  setTimeout(resolve, 500, 1)

})

const p2 = new Promise((resolve, reject) => {

  setTimeout(resolve, 100, 2)

})

Promise.myRace([p1, p2]).then((value) => {

  console.log(value) // 2

})

Promise.myRace([p1, p2, 3]).then((value) => {

  console.log(value) // 3

})

结尾

也许你我素未谋面,但很可能相见恨晚。希望这里能成为你的栖息之地,我愿和你一起收获喜悦,奔赴成长。

 

相关文章:

面试手写实现Promise.all

目录 前言常见面试手写系列Promise.resolve 简要回顾源码实现Promise.reject 简要回顾源码实现Promise.all 简要回顾源码实现Promise.allSettled 简要回顾源码实现Promise.race 简单回顾源码实现结尾 前言 (?﹏?)曾经真实发生在一个朋友身上的真实事件&#xff0c;面试官让…...

TCP网络通信编程之字符流

【案例1】 【题目描述】 【 注意事项】 (3条消息) 节点流和处理流 字符处理流BufferedReader、BufferedWriter&#xff0c;字节处理流-BufferedInputStream和BufferedOutputStream (代码均正确且可运行_Studying~的博客-CSDN博客 1。这里需要使用字符处理流&#xff0c;来将…...

佰维存储面向旗舰智能手机推出UFS3.1高速闪存

手机“性能铁三角”——SoC、运行内存、闪存决定了一款手机的用户体验和定位&#xff0c;其中存储器性能和容量对用户体验的影响越来越大。 针对旗舰智能手机&#xff0c;佰维推出了UFS3.1高速闪存&#xff0c;写入速度最高可达1800MB/s&#xff0c;是上一代通用闪存存储的4倍以…...

降龙十八掌

目录 大数据&#xff1a; 1 HIVE&#xff1a; 1.1 HIVE QL 1.1.1 创建表 1.1.2 更新表 1.1.3 常用语句 1.2 hive参数配置 大数据&#xff1a; 1 HIVE&#xff1a; 1.1 HIVE QL DDL中常用的命令有&#xff1a;create&#xff0c;drop&#xff0c;alter&#xff0c;trunc…...

【项目设计】MySQL 连接池的设计

目录 &#x1f449;关键技术点&#x1f448;&#x1f449;项目背景&#x1f448;&#x1f449;连接池功能点介绍&#x1f448;&#x1f449;MySQL Server 参数介绍&#x1f448;&#x1f449;功能实现设计&#x1f448;&#x1f449;开发平台选型&#x1f448;&#x1f449;MyS…...

Ubuntu系统adb开发调试问题记录

Ubuntu系统adb开发调试问题记录 一、adb devices no permissions二、自定义adb server端口三、动态库目录四、USB抓包 一、adb devices no permissions lsusb -t 设备树直观地查看设备的Bus ID和Device Num&#xff0c;lsusb找到对应的PID和VID编辑udev规则 sudo vim /etc/ud…...

【宏定义】——检验条件是否成立,并返回指定的值

文章目录 功能说明实现示例解析扩展 功能说明 宏检验条件是否成立&#xff0c;并返回指定的值 #define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)TU_VERIFY(1) 检验为真&#xff0c;啥也不干TU_VERIFY(0) 校验为假&…...

UE5引擎源码小记 —反射信息注册过程

序 最近看了看反射相关的知识&#xff0c;用不说一点人话的方式来说&#xff0c;反射是程序在运行中能够动态获取修改或调用自身属性的东西。 一开始我是觉得反射用处好像不大&#xff0c;后续查了下一些反射的使用环境&#xff0c;发现我格局小了&#xff0c;我觉得用处不大的…...

Redis缓存预热

说明&#xff1a;项目中使用到Redis&#xff0c;正常情况&#xff0c;我们会在用户首次查询数据的同时把该数据按照一定命名规则&#xff0c;存储到Redis中&#xff0c;称为冷启动&#xff08;如下图&#xff09;&#xff0c;这种方式在一些情况下可能会给数据库带来较大的压力…...

Android 耗时分析(adb shell/Studio CPU Profiler/插桩Trace API)

1.adb logcat 查看冷启动时间和Activity显示时间&#xff1a; 过滤Displayed关键字&#xff0c;可看到Activity的显示时间 那上面display后面的是时间是指包含哪些过程的时间呢&#xff1f; 模拟在Application中沉睡1秒操作&#xff0c;冷启动情况下&#xff1a; 从上可知&…...

保护隐私与安全的防关联、多开浏览器

随着互联网的不断发展&#xff0c;我们越来越离不开浏览器这个工具&#xff0c;它为我们提供了便捷的网络浏览体验。然而&#xff0c;随着我们在互联网上的活动越来越多&#xff0c;我们的个人信息和隐私也日益暴露在网络风险之下。在这种背景下&#xff0c;为了保护个人隐私和…...

CloudStudio搭建Next框架博客_抛开电脑性能在云端编程(沉浸式体验)

文章目录 ⭐前言⭐进入cloud studio工作区指引&#x1f496; 注册coding账号&#x1f496; 选择cloud studio&#x1f496; cloud studio选择next.js&#x1f496; 安装react的ui框架&#xff08;tDesign&#xff09;&#x1f496; 安装axios&#x1f496; 代理请求跨域&#x…...

【FPGA IP系列】FIFO深度计算详解

FIFO(First In First Out)是一种先进先出的存储结构&#xff0c;经常被用来在FPGA设计中进行数据缓存或者匹配传输速率。 FIFO的一个关键参数是其深度&#xff0c;也就是FIFO能够存储的数据条数&#xff0c;深度设计的合理&#xff0c;可以防止数据溢出&#xff0c;也可以节省…...

JavaScript中语句和表达式

在JavaScript编程中&#xff0c;Statements和Expressions都是代码的构建块&#xff0c;但它们有不同的特点和用途。 ● Statements&#xff08;语句&#xff09;是执行某些操作的完整命令&#xff1b;每个语句通常以分号结束。例如&#xff0c;if语句、for语句、switch语句、函…...

打卡力扣题目十

#左耳听风 ARST 打卡活动重启# 目录 一、题目 二、解决方法一 三、解决方法二 关于 ARTS 的释义 —— 每周完成一个 ARTS&#xff1a; ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个技术技巧 ● Shar…...

UniApp实现API接口封装与请求方法的设计与开发方法

UniApp实现API接口封装与请求方法的设计与开发方法 导语&#xff1a;UniApp是一个基于Vue.js的跨平台开发框架&#xff0c;可以同时开发iOS、Android和H5应用。在UniApp中&#xff0c;实现API接口封装与请求方法的设计与开发是一个十分重要的部分。本文将介绍如何使用UniApp实…...

利用小波分解信号,再重构

function [ output_args ] example4_5( input_args ) %EXAMPLE4_5 Summary of this function goes here % Detailed explanation goes here clc; clear; load leleccum; s leleccum(1:3920); % 进行3层小波分解&#xff0c;小波基函数为db2 [c,l] wavedec(s,3,db2); %进行…...

QT数据库编程

ui界面 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QButtonGroup> #include <QFileDialog> #include <QMessageBox> MainWindow::MainWindow(QWidget* parent): QMainWindow(parent), ui(new Ui::M…...

基于stm32单片机的直流电机速度控制——LZW

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、实验目的二、实验方法三、实验设计1.实验器材2.电路连接3.软件设计&#xff08;1&#xff09;实验变量&#xff08;2&#xff09;功能模块a&#xff09;电机接收信号…...

实际项目中使用mockjs模拟数据

项目中的痛点 自己模拟的数据对代码的侵入程度太高&#xff0c;接口完成后要删掉对应的代码&#xff0c;导致接口开发完后端同事开发完&#xff0c;前端自己得加班&#xff1b;接口联调的时间有可能会延期&#xff0c;接口完成的质量参差不齐&#xff1b;对于数据量过大的模拟…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...