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

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

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6052

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 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 

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    开心
    2022-9-11 10:49
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    13

    主题

    276

    回帖

    251

    积分

    版主

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

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6052

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

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

    准备攒一段时间再慢慢录,想最近先大概捋出来一些知识点,呜呜呜
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6052

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

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

    虽然录了也没什么人看,超过1分钟以后视频播放人数不超过10个
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    861

    回帖

    1360

    积分

    荣誉开发者

    积分
    1360

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

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

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


    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-9-11 10:49
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    13

    主题

    276

    回帖

    251

    积分

    版主

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

    影响力在后面
    回复

    使用道具 举报

  • TA的每日心情
    开心
    1 小时前
  • 签到天数: 705 天

    [LV.9]以坛为家II

    27

    主题

    733

    回帖

    7214

    积分

    荣誉开发者

    精通各种语言的HelloWord!

    积分
    7214

    荣誉开发者油中2周年生态建设者油中3周年挑战者 lv2

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

    使用道具 举报

    发表回复

    本版积分规则

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