上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

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

[复制链接]

182

主题

1388

帖子

757

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
757
发表于 2021-8-22 14:58:57 | 显示全部楼层 | 阅读模式

前文

这里介绍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函数。

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

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

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

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

Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失败了,打出 '失败'
})

Promise.allSettled

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

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

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

Promise.race

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

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

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

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

Promise.resolve

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

图片.png

Promise.reject

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

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

图片.png

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

async与await

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

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

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

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

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

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

图片.png

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

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 某个函数也是可以正常执行的。

结语

撒花~

已有1人评分好评 油猫币 贡献 理由
陈公子的话 + 1 + 1 + 1 ggnb!

查看全部评分 总评分:好评 +1  油猫币 +1  贡献 +1 

混的人。

8

主题

159

帖子

203

积分

开发者

Rank: 6Rank: 6

积分
203

活跃会员热心会员突出贡献三好学生猫咪币纪念章中秋纪念章国庆纪念章

发表于 2021-8-22 20:07:58 | 显示全部楼层
本帖最后由 cxxjackie 于 2021-8-22 20:13 编辑

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


回复

使用道具 举报

11

主题

196

帖子

101

积分

版主

Rank: 7Rank: 7Rank: 7

积分
101

猫咪币纪念章活跃会员中秋纪念章国庆纪念章

发表于 2021-8-22 19:31:30 | 显示全部楼层
高产!什么时候录视频
回复

使用道具 举报

182

主题

1388

帖子

757

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
757
发表于 2021-8-22 19:57:10 | 显示全部楼层
水凛子 发表于 2021-8-22 19:31
高产!什么时候录视频

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

使用道具 举报

182

主题

1388

帖子

757

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
757
发表于 2021-8-22 19:57:27 | 显示全部楼层
水凛子 发表于 2021-8-22 19:31
高产!什么时候录视频

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

使用道具 举报

11

主题

196

帖子

101

积分

版主

Rank: 7Rank: 7Rank: 7

积分
101

猫咪币纪念章活跃会员中秋纪念章国庆纪念章

发表于 2021-8-22 21:02:15 | 显示全部楼层
李恒道 发表于 2021-8-22 19:57
虽然录了也没什么人看,超过1分钟以后视频播放人数不超过10个

影响力在后面
回复

使用道具 举报

12

主题

224

帖子

1770

积分

开发者

Rank: 6Rank: 6

积分
1770

猫咪币纪念章活跃会员三好学生热心会员中秋纪念章国庆纪念章

发表于 2021-8-22 21:37:06 | 显示全部楼层
哥哥高产了
布[
回复

使用道具 举报

发表回复

本版积分规则

快速回复 返回顶部 返回列表