李恒道 发表于 2021-8-22 14:58:57

[油猴脚本开发指南]Promise常用函数与语法糖

# 前文

这里介绍promise一些常用的函数以及一个语法糖,方便编写代码的过程中更加方便~4

本文使用了引用的资料以及代码如下

https://www.jianshu.com/p/7e60fc1be1b2

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/race

# Promise.all

Promise.all相当于把一堆promise请求当成一个数组,当这个数组全部履行完毕,检查是否全部成功,如果全部成功,则将返回内容合并成一个数组返回给then里,如果其中一个失败,则调用catch函数。

```javascript
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
resolve('success')
})

let p3 = Promse.reject('失败')

Promise.all().then((result) => {
console.log(result)               //['成功了', 'success']
}).catch((error) => {
console.log(error)
})

Promise.all().then((result) => {
console.log(result)
}).catch((error) => {
console.log(error)      // 失败了,打出 '失败'
})
```

# Promise.allSettled

与Promise.All相似的还有一个allSettled,allSettled不追求全部成功,即使在promise数组中存在失败的promise依然会正常调用then函数

```javascript
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = ;

Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result.status)));
```

# Promise.race

Promise.race相当于一个竞速,一旦列表中某个promise执行完毕了,就会立刻返回第一个执行完毕的内容,需要注意,虽然第一个执行完毕了,但是其他Promise依然会正常执行至结束

```javascript
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});

Promise.race().then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
// expected output: "two"
```

# Promise.resolve

Promise.resolve将一个值包装成一个Promise对象,如果这个值是Promise则直接返回,如果不是Promise则包装成Promise对象

![图片.png](data/attachment/forum/202108/22/145105ild6s68r9jjl8cct.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

# Promise.reject

Promise.reject将一个值包装成一个Promise对象,与resolve不同的是,这个包装的对象是rejected属性

我们可以通过catch捕获他的值,如果不进行catch捕获,将会提示未捕获错误

![图片.png](data/attachment/forum/202108/22/145855u42oq48y8nlu3ya2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

为什么说包装的对象是rejected属性,而我们返回的是一个fulfilled属性?因为这个promise后跟随了catch函数,我们返回的这个Promise是由catch进行错误处理后返回的Promise。

# async与await

当执行Promise相当于一个异步,在他执行后会自动传到then上进行处理,那我们有没有办法让他变成同步代码?就是使用async与await

await后面跟随一个Promise会阻塞后续代码的运行,想要使用await必须是async函数

```javascript
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
});
}

async function f1() {
var x = await resolveAfter2Seconds(10);
console.log(x); // 10
}
f1();


```

这里我们声明了一个f1函数,为了将promise变为同步代码,使用了await和async,直至resolveAfter2Seconds返回内容后才会继续执行,并将结果赋值给x,输出x

```javascript
function resolveAfter2Seconds(x) {
return new Promise((resolve,reject) => {
    setTimeout(() => {
      reject(x);
    }, 2000);
});
}

async function f1() {
    try {
      var x = await resolveAfter2Seconds(10);
    } catch (err) {
      console.log('我发生了错误',err)
    }
console.log(x); // 10
}
f1();
```

当await返回的Promise是reject的时候,不会赋值到x上,这时候我们需要用try+catch来捕获reject,在try{}内添加可能发生错误的代码段,然后跟随catch(err){},当try{}内发生错误的时候就会自动调用catch函数捕获错误(有没有很像Promise的catch)

![图片.png](data/attachment/forum/202108/22/150917s55a85c8xxxicwhz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

这里可以看到catch内捕获了发生错误的值

这样我们就学习了如果将同步包装成异步,但是还需要注意一个问题,当函数加上async后,函数也会变成一个promise对象。会将返回的值变成promise对象的value

![图片.png](data/attachment/forum/202108/22/151130uqi2mrd3qrdgdt2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

也就是说其他函数想要调用f1并形成同步代码,那自身也要加上async,并await f1函数

```javascript
function resolveAfter2Seconds(x) {
return new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
});
}

async function f1() {
    try {
      var x = await resolveAfter2Seconds(10);
    } catch (err) {
      console.log('我发生了错误',err)
    }
return 6666
}

async function f1await(){
var f1value=await f1()
console.log(f1value)
}
```

这里我们同步了f1,但是f1await又变成了async函数(套娃)

那这里就基本讲述完毕了Promise的基本概念了!

如果到这里你全部清楚明白,那我可以说你已经很棒了!

最后让我们用一个冷知识结尾。

## 冷知识

关于全局使用await函数目前还没有实现,但是根据查阅资料,在全局空间使用await有提上日程,可能在以后我们在全局状态下直接await 某个函数也是可以正常执行的。

# 结语

撒花~

cxxjackie 发表于 2021-8-22 20:07:58

本帖最后由 cxxjackie 于 2021-8-22 20:13 编辑

推荐两篇文章:
https://segmentfault.com/a/1190000014753495
https://mp.weixin.qq.com/s/qdJ0Xd8zTgtetFdlJL3P1g
第一篇的代码示例写的不太好,理解意思就行了,新手容易犯的错误。
第二篇的第一部分可以跳过不看。


水凛子 发表于 2021-8-22 19:31:30

高产!什么时候录视频

李恒道 发表于 2021-8-22 19:57:10

水凛子 发表于 2021-8-22 19:31
高产!什么时候录视频

准备攒一段时间再慢慢录,想最近先大概捋出来一些知识点,呜呜呜

李恒道 发表于 2021-8-22 19:57:27

水凛子 发表于 2021-8-22 19:31
高产!什么时候录视频

虽然录了也没什么人看,超过1分钟以后视频播放人数不超过10个

水凛子 发表于 2021-8-22 21:02:15

李恒道 发表于 2021-8-22 19:57
虽然录了也没什么人看,超过1分钟以后视频播放人数不超过10个

{:4_95:}影响力在后面

Ne-21 发表于 2021-8-22 21:37:06

哥哥高产了
页: [1]
查看完整版本: [油猴脚本开发指南]Promise常用函数与语法糖