<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Gregoria</title>
        <link>https://paragraph.com/@gregoria</link>
        <description>undefined</description>
        <lastBuildDate>Mon, 01 Jun 2026 14:57:26 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Gregoria</title>
            <url>https://storage.googleapis.com/papyrus_images/83b74516bc5a72a7975191ae28332aef91579966037b6b202169d0768292e8e6.webp</url>
            <link>https://paragraph.com/@gregoria</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[冬闲]]></title>
            <link>https://paragraph.com/@gregoria/k1i0pqNLidmyXcA3reGo</link>
            <guid>k1i0pqNLidmyXcA3reGo</guid>
            <pubDate>Fri, 05 Aug 2022 04:41:20 GMT</pubDate>
            <description><![CDATA[冬天，庄户人家就进入了冬闲，可我的母亲怎么也闲不下来。 鸡叫头遍，母亲蹑手蹑脚地起床，轻轻划过一根火柴，点亮煤油灯，扒炉膛里灰烬，刮锅底黑灰，拔草垛抱草，煮早饭，烧猪食，备鸡粮……天亮，开鸡窝门，捉鸡摸鸡屁股“寸蛋”，一只鸡一只鸡地“过堂”，像皇帝选美一样。接下来，提个“粪兜”出去拾粪。母亲言，早起三光，晚起三慌，鸡屎全被人“抢”光！ 日上竿头，母亲笑眯眯地看太阳升起，趁好太阳洗衣服吧，一家七八口人的衣服都要洗呢。草屋檐下一排闪闪发亮的“银钉”都有尺把长，却丝毫没有“瘦身”的趋势。河里水早冰冻三尺，母亲挥舞榔头拼命捶打，嘎吱一声，破冰了。把衣服一件一件地在冰冷的河水里汰洗。母亲忍着刺骨的冰水，直至手冻麻木了，才把手伸到腋窝处暖一下，稍有知觉，便又立马接着清洗衣服。 中午，暖阳化冻。母亲眉开眼笑，扛钉耙，挎柳篮，下地镞“二遍”荸荠、茨菇，拿到集上卖能卖角把钱一斤呢。可她“鹅掌风”手，与泥土亲密接触，更加皲裂不堪，血流不止。抓过母亲手，问她疼否？母亲直笑：没事，闲下来才疼，干活就不疼！我心里疼得要命，却没有能力阻止母亲的劳碌。 母亲说：“活不会找人，只有人去找活”。晌午，母亲要把猪圈...]]></description>
            <content:encoded><![CDATA[<p>冬天，庄户人家就进入了冬闲，可我的母亲怎么也闲不下来。</p><p>鸡叫头遍，母亲蹑手蹑脚地起床，轻轻划过一根火柴，点亮煤油灯，扒炉膛里灰烬，刮锅底黑灰，拔草垛抱草，煮早饭，烧猪食，备鸡粮……天亮，开鸡窝门，捉鸡摸鸡屁股“寸蛋”，一只鸡一只鸡地“过堂”，像皇帝选美一样。接下来，提个“粪兜”出去拾粪。母亲言，早起三光，晚起三慌，鸡屎全被人“抢”光！</p><p>日上竿头，母亲笑眯眯地看太阳升起，趁好太阳洗衣服吧，一家七八口人的衣服都要洗呢。草屋檐下一排闪闪发亮的“银钉”都有尺把长，却丝毫没有“瘦身”的趋势。河里水早冰冻三尺，母亲挥舞榔头拼命捶打，嘎吱一声，破冰了。把衣服一件一件地在冰冷的河水里汰洗。母亲忍着刺骨的冰水，直至手冻麻木了，才把手伸到腋窝处暖一下，稍有知觉，便又立马接着清洗衣服。</p><p>中午，暖阳化冻。母亲眉开眼笑，扛钉耙，挎柳篮，下地镞“二遍”荸荠、茨菇，拿到集上卖能卖角把钱一斤呢。可她“鹅掌风”手，与泥土亲密接触，更加皲裂不堪，血流不止。抓过母亲手，问她疼否？母亲直笑：没事，闲下来才疼，干活就不疼！我心里疼得要命，却没有能力阻止母亲的劳碌。</p><p>母亲说：“活不会找人，只有人去找活”。晌午，母亲要把猪圈里的粪便清理出来，因猪常在圈里“大闹天宫”，或“越狱”而逃，麦子也该补充营养了。这力气活原是父亲干的，可父亲到了冬闲，不是去远地“挑河工”，就是到上海“挑大粪”，或去山东“裝煤灰”“牛屎饼”，少在家。尽管是寒冷的冬天，那猪粪还是很远就能闻到臭味的。母亲却说，越臭越好！晚饭后，母亲又在煤油灯下给我们缝补衣服、纳鞋底、捻线等。母亲把针和线举到昏暗的灯前，眯觑着眼睛艰难地缝着，手太冷时，就用双手对搓一下，或放嘴边哈一口热气，继续干活。有时太累，打了个盹，手被针一戳，血直冒！母亲随即用嘴一啜：真鲜。母亲不爱凑热闹，说人多的地方话多，那样会影响做事。</p><p>除一日三餐和干不完的家务外，母亲有时还“借月浇水”。凄冷空旷的田野上，母亲只身一人，在星月下，刷刷刷，哗哗哗，一道道白浪划过麦田的上空，飘飘然洒在麦身上……饥渴的麦子朗朗地笑了。</p><p>逢集日，母亲要走一小时土路赶集，把起早贪黑编的柴帘，搓的草绳，或打下的杂豆等，卖掉，积攒点钱过年，还有我们的学费。平时，母亲还要捡柴禾。母亲佝偻着腰，抖动着双手，将一根根柴禾拢在怀里，一小捆拾了半天。冬阳下，柴禾影子拉得细长，像母亲身躯一般瘦。一阵寒风呼啸而来，恶狼似的扑向母亲，母亲如同一片单薄的枯叶，随时都可能被大风刮走……但母亲还是坚强地将沉重的柴禾背回了家，一家老小张着嘴巴等她煮饭呢。</p><p>逢雨雪天，母亲该歇了吧。不！她冷不丁的端出一筐“核桃”（死果子棉桃），一只一只地用手剥出僵硬的棉絮，或搂着一捆新稻草，将遗留在草上的稻粒，一颗一颗地抠下来……记忆里，母亲24小时除了少得可怜的几小时睡眠外，她一刻不闲。印象中的母亲，永远像一只陀螺，转啊，转啊，直至转到生命止息……</p>]]></content:encoded>
            <author>gregoria@newsletter.paragraph.com (Gregoria)</author>
        </item>
        <item>
            <title><![CDATA[《听听那冷雨》 --- 余光中]]></title>
            <link>https://paragraph.com/@gregoria/lLIEZM2ewquZ8HTAem1o</link>
            <guid>lLIEZM2ewquZ8HTAem1o</guid>
            <pubDate>Sun, 08 May 2022 13:54:07 GMT</pubDate>
            <description><![CDATA[惊蛰一过，春寒加剧。先是料料峭峭，继而雨季开始，时而淋淋漓漓，时而淅淅沥沥，天潮潮地湿湿，即连在梦里，也似乎有把伞撑着。而就凭一把伞，躲过一阵潇潇的冷雨，也躲不过整个雨季。连思想也都是潮润润的。每天回家，曲折穿过金门街到厦门街迷宫式的长巷短巷，雨里风里，走入霏霏令人更想入非非。想这样子的台北凄凄切切完全是黑白片的味道，想整个中国整部中国的历史无非是一张黑白片子，片头到片尾，一直是这样下着雨的。这种感觉，不知道是不是从安东尼奥尼那里来的。不过那—块土地是久违了，二十五年，四 分之一的世纪，即使有雨，也隔着千山万山，千伞万伞。十五年，一切都断了，只有气候，只有气象报告还牵连在一起，大寒流从那块土地上弥天卷来，这种酷冷吾与古大陆分担。不能扑进她怀里，被她的裙边扫一扫也算是安慰孺慕之情吧。 这样想时，严寒里竟有一点温暖的感觉了。这样想时，他希望这些狭长的巷子永远延伸下去，他的思路也可以延伸下去，不是金门街到厦门街，而是金门到厦门。他是厦门人，至少是广义的厦门人，二十年来，不住在厦门，住在厦门街，算是嘲弄吧，也算是安慰。不过说到广义，他同样也是广义的江南人，常州人，南京人，川娃儿，五陵少年...]]></description>
            <content:encoded><![CDATA[<p>惊蛰一过，春寒加剧。先是料料峭峭，继而雨季开始，时而淋淋漓漓，时而淅淅沥沥，天潮潮地湿湿，即连在梦里，也似乎有把伞撑着。而就凭一把伞，躲过一阵潇潇的冷雨，也躲不过整个雨季。连思想也都是潮润润的。每天回家，曲折穿过金门街到厦门街迷宫式的长巷短巷，雨里风里，走入霏霏令人更想入非非。想这样子的台北凄凄切切完全是黑白片的味道，想整个中国整部中国的历史无非是一张黑白片子，片头到片尾，一直是这样下着雨的。这种感觉，不知道是不是从安东尼奥尼那里来的。不过那—块土地是久违了，二十五年，四</p><p>分之一的世纪，即使有雨，也隔着千山万山，千伞万伞。十五年，一切都断了，只有气候，只有气象报告还牵连在一起，大寒流从那块土地上弥天卷来，这种酷冷吾与古大陆分担。不能扑进她怀里，被她的裙边扫一扫也算是安慰孺慕之情吧。</p><p>这样想时，严寒里竟有一点温暖的感觉了。这样想时，他希望这些狭长的巷子永远延伸下去，他的思路也可以延伸下去，不是金门街到厦门街，而是金门到厦门。他是厦门人，至少是广义的厦门人，二十年来，不住在厦门，住在厦门街，算是嘲弄吧，也算是安慰。不过说到广义，他同样也是广义的江南人，常州人，南京人，川娃儿，五陵少年。杏花春雨江南，那是他的少年时代了。再过半个月就是清明。安东尼奥尼的镜头摇过去，摇过去又摇过来。残山剩水犹如是，皇天后土犹如是。纭纭黔首、纷纷黎民从北到南犹如是。那里面是中国吗?那里面当然还是中国永远是中国。只是杏花春雨已不再，牧童遥指已不再，剑门细雨渭城轻尘也都已不再。然则他日思夜梦的那片土地，究竟在哪里呢?</p><p>在报纸的头条标题里吗?还是香港的谣言里?还是傅聪的黑键白键马恩聪的跳弓拨弦?还是安东尼奥尼的镜底勒马洲的望中?还是呢，故宫博物院的壁头和玻璃柜内，京戏的锣鼓声中太白和东坡的韵里?</p><p>杏花，春雨，江南。六个方块字，或许那片土就在那里面。而无论赤县也好神州也好中国也好，变来变去，只要仓颉的灵感不灭，美丽的中文不老，那形象那磁石一般的向心力当必然长在。因为一个方块字是一个天地。太初有字，于是汉族的心灵他祖先的回忆和希望便有了寄托。譬如凭空写一个“雨”字，点点滴滴，滂滂沱沱，淅淅沥沥，一切云情雨意，就宛然其中了。视觉上的这种美感，岂是什么rain也好pluie也好所能满足?翻开一部《辞源》或《辞海》，金木水火土，各成世界，而一入“雨”部，古神州的天颜千变万化，便悉在望中，美丽的霜雪云霞，骇人的雷电霹雹，展露的无非是神的好脾气与坏脾气，气象台百读不厌门外汉百思不解的百科全书。</p><p>听听，那冷雨。看看，那冷雨。嗅嗅闻闻，那冷雨，舔舔吧，那冷雨。雨在他的伞上这城市百万人的伞上雨衣上屋上天线上，雨下在基隆港在防波堤海峡的船上，清明这季雨。雨是女性，应该最富于感性。雨气空而迷幻，细细嗅嗅，清清爽爽新新，有一点点薄荷的香味，浓的时候，竟发出草和树林之后特有的淡淡土腥气，也许那竟是蚯蚓的蜗牛的腥气吧，毕竟是惊蛰了啊。也许地上的地下的生命也许古中国层层叠叠的记忆皆蠢蠢而蠕，也许是植物的潜意识和梦紧，那腥气。</p><p>第三次去美国，在高高的丹佛他山居住了两年。美国的西部，多山多沙漠，千里干旱，天，蓝似安格罗萨克逊人的眼睛，地，红如印第安人的肌肤，云，却是罕见的白鸟，落基山簇簇耀目的雪峰上，很少飘云牵雾。一来高，二来干，三来森林线以上，杉柏也止步，中国诗词里“荡胸生层云”或是“商略黄昏雨”的意趣，是落基山上难睹的景象。落基山岭之胜，在石，在雪。那些奇岩怪石，相叠互倚，砌一场惊心动魄的雕塑展览，给太阳和千里的风看。那雪，白得虚虚幻幻，冷得清清醒醒，那股皑皑不绝一仰难尽的气势，压得人呼吸困难，心寒眸酸。不过要领略“白云回望合，青露入看无”的境界，仍须来中国。台湾湿度很高，最饶云气氛题雨意迷离的情调。两度夜宿溪头，树香沁鼻，宵寒袭肘，枕着润碧湿翠苍苍交叠的山影和万缀都歇的俱寂，仙人一样睡去。山中一夜饱雨，次晨醒来，在旭日未升的原始幽静中，冲着隔夜的寒气，踏着满地的断柯折枝和仍在流泻的细股雨水，一径探入森林的秘密，曲曲弯弯，步上山去。溪头的山，树密雾浓，蓊郁的水气从谷底冉冉升起，时稠时稀，蒸腾多姿，幻化无定，只能从雾破云开的空处，窥见乍现即隐的一峰半堑，要纵览全貌，几乎是不可能的。至少上山两次，只能在白茫茫里和溪头诸峰玩捉迷藏的游戏。回到台北，世人问起，除了笑而不答心自问，故作神秘之外，实际的印象，也无非山在虚无之间罢了。云绦烟绕，山隐水迢的中国风景，由来予人宋画的韵味。那天下也许是赵家的天下，那山水却是米家的山水。而究竟，是米氏父子下笔像中国的山水，还是中国的山水上只像宋画，恐怕是谁也说不清楚了吧?</p><p>雨不但可嗅，可亲，更可以听。听听那冷雨。听雨，只要不是石破天惊的台风暴雨，在听觉上总是一种美感。大陆上的秋天，无论是疏雨滴梧桐，或是骤雨打荷叶，听去总有一点凄凉，凄清，凄楚，于今在岛上回味，则在凄楚之外，再笼上一层凄迷了，饶你多少豪情侠气，怕也经不起三番五次的风吹雨打。一打少年听雨，红烛昏沉。再打中年听雨，客舟中江阔云低。三打白头听雨的僧庐下，这更是亡宋之痛，一颗敏感心灵的一生：楼上，江上，庙里，用冷冷的雨珠子串成。十年前，他曾在一场摧心折骨的鬼雨中迷失了自己。雨，该是一滴湿漓漓的灵魂，窗外在喊谁。</p><p>雨打在树上和瓦上，韵律都清脆可听。尤其是铿铿敲在屋瓦上，那古老的音乐，属于中国。王禹的黄冈，破如椽的大竹为屋瓦。据说住在竹楼上面，急雨声如瀑布，密雪声比碎玉，而无论鼓琴，咏诗，下棋，投壶，共鸣的效果都特别好。这样岂不像住在竹和筒里面，任何细脆的声响，怕都会加倍夸大，反而令人耳朵过敏吧。</p><p>雨天的屋瓦，浮漾湿湿的流光，灰而温柔，迎光则微明，背光则幽黯，对于视觉，是一种低沉的安慰。至于雨敲在鳞鳞千瓣的瓦上，由远而近，轻轻重重轻轻，夹着一股股的细流沿瓦槽与屋檐潺潺泻下，各种敲击音与滑音密织成网，谁的千指百指在按摩耳轮。“下雨了”，温柔的灰美人来了，她冰冰的纤手在屋顶拂弄着无数的黑键啊灰键，把晌午一下子奏成了黄昏。</p><p>在古老的大陆上，千屋万户是如此。二十多年前，初来这岛上，日式的瓦屋亦是如此。先是天黯了下来，城市像罩在一块巨幅的毛玻璃里，阴影在户内延长复加深。然后凉凉的水意弥漫在空间，风自每一个角落里旋起，感觉得到，每一个屋顶上呼吸沉重都覆着灰云。雨来了，最轻的敲打乐敲打这城市。苍茫的屋顶，远远近近，一张张敲过去，古老的琴，那细细密密的节奏，单调里自有一种柔婉与亲切，滴滴点点滴滴，似幻似真，若孩时在摇篮里，一曲耳熟的童谣摇摇欲睡，母亲吟哦鼻音与喉音。或是在江南的泽国水乡，一大筐绿油油的桑叶被啮于千百头蚕，细细琐琐屑屑，口器与口器咀咀嚼嚼。雨来了，雨来的时候瓦这幺说，一片瓦说千亿片瓦说，说轻轻地奏吧沉沉地弹，徐徐地叩吧挞挞地打，间间歇歇敲一个雨季，即兴演奏从惊蛰到清明，在零落的坟上冷冷奏挽歌，一片瓦吟千亿片瓦吟。</p><p>在旧式的古屋里听雨，听四月，霏霏不绝的黄梅雨，朝夕不断，旬月绵延，湿黏黏的苔藓从石阶下一直侵到舌底，心底。到七月，听台风台雨在古屋顶上一夜盲奏，千层海底的热浪沸沸被狂风挟挟，掀翻整个太平洋只为向他的矮屋檐重重压下，整个海在他的蝎壳上哗哗泻过。不然便是雷雨夜，白烟一般的纱帐里听羯鼓一通又一通，滔天的暴雨滂滂沛沛扑来，强劲的电琵琶忐忐忑忑忐忐忑忑，弹动屋瓦的惊悸腾腾欲掀起。不然便是斜斜的西北雨斜斜刷在窗玻璃上，鞭在墙上打在阔大的芭蕉叶上，一阵寒潮泻过，秋意便弥湿旧式的庭院了。</p><p>在旧式的古屋里听雨，春雨绵绵听到秋雨潇潇，从少年听到中年，听听那冷雨。雨是一种单调而耐听的音乐是室内乐是室外乐，户内听听，户外听听，冷冷，那音乐。雨是一种回忆的音乐，听听那冷雨，回忆江南的雨下得满地是江湖下在桥上和船上，也下在四川在秧田和蛙塘，—下肥了嘉陵江下湿布谷咕咕的啼声，雨是潮潮润润的音乐下在渴望的唇上，舔舔那冷雨。</p><p>因为雨是最最原始的敲打乐从记忆的彼端敲起。瓦是最最低沉的乐器灰蒙蒙的温柔覆盖着听雨的人，瓦是音乐的雨伞撑起。但不久公寓的时代来临，台北你怎么一下子长高了，瓦的音乐竟成了绝响。千片万片的瓦翩翩，美丽的灰蝴蝶纷纷飞走，飞入历史的记忆。现在雨下下来下在水泥的屋顶和墙上，没有音韵的雨季。树也砍光了，那月桂，那枫树，柳树和擎天的巨椰，雨来的时候不再有丛叶嘈嘈切切，闪动湿湿的绿光迎接。鸟声减了啾啾，蛙声沉了咯咯，秋天的虫吟也减了唧唧。七十年代的台北不需要这些，一个乐队接一个乐队便遣散尽了。要听鸡叫，只有去诗经的韵里找。现在只剩下一张黑白片，黑白的默片。</p><p>正如马车的时代去后，三轮车的夫工也去了。曾经在雨夜，三轮车的油布篷挂起，送她回家的途中，篷里的世界小得多可爱，而且躲在警察的辖区以外，雨衣的口袋越大越好，盛得下他的一只手里握一只纤纤的手。台湾的雨季这么长，该有人发明一种宽宽的双人雨衣，一人分穿一只袖子此外的部分就不必分得太苛。而无论工业如何发达，一时似乎还废不了雨伞。只要雨不倾盆，风不横吹，撑一把伞在雨中仍不失古典的韵味。任雨点敲在黑布伞或是透明的塑胶伞上，将骨柄一旋，雨珠向四方喷溅，伞缘便旋成了一圈飞檐。跟女友共一把雨伞，该是一种美丽的合作吧。最好是初恋，有点兴奋，更有点不好意思，若即若离之间，雨不妨下大一点。真正初恋，恐怕是兴奋得不需要伞的，手牵手在雨中狂奔而去，把年轻的长发的肌肤交给漫天的淋淋漓漓，然后向对方的唇上颊上尝凉凉甜甜的雨水。不过那要非常年轻且激情，同时，也只能发生在法国的新潮片里吧。</p><p>大多数的雨伞想不会为约会张开。上班下班，上学放学，菜市来回的途中。现实的伞，灰色的星期三。握着雨伞。他听那冷雨打在伞上。索性更冷一些就好了，他想。索性把湿湿的灰雨冻成干干爽爽的白雨，六角形的结晶体在无风的空中回回旋旋地降下来。等须眉和肩头白尽时，伸手一拂就落了。二十五年，没有受故乡白雨的祝福，或许发上下一点白霜是一种变相的自我补偿吧。一位英雄，经得起多少次雨季?他的额头是水成岩削成还是火成岩?他的心底究竟有多厚的苔藓?厦门街的雨巷走了二十年与记忆等长，—座无瓦的公寓在巷底等他，一盏灯在楼上的雨窗子里，等他回去，向晚餐后的沉思冥想去整理青苔深深的记忆。</p><p>前尘隔海。古屋不再。听听那冷雨。</p>]]></content:encoded>
            <author>gregoria@newsletter.paragraph.com (Gregoria)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/397a4cd28083b5a45a20018a1eb4d6ad8e3171d9d3e556783fbddff9f6baa2c8.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[es6-Promise]]></title>
            <link>https://paragraph.com/@gregoria/es6-promise</link>
            <guid>mvNIdY5WP6sx3N4wk7jY</guid>
            <pubDate>Tue, 09 Nov 2021 02:59:28 GMT</pubDate>
            <description><![CDATA[如果世界上所有的表白都能成功的话，那这个世界就不会存在像我这样的人了。 晚上我回到宿舍将我要表白她的事告诉了室友，室友纷纷当起了劝退师，觉得我压根配不上她，她有太多优质的选择。陷入爱河的我已经听不进任何人的劝阻了，只要有百分之零点一的机会我就想尝试下。于是接下来的几天我一直在计划我的表白了...... 终于等到那天，今天的天气额外的宁静清爽，我以各种借口约她晚上去操场走走，起初她并不愿意，在我的死打烂缠下终于答应了。我提前买好了她喜欢的抹茶味奶茶，少糖。现在仍然记得等待时的心情，激动，紧张，充满期待，没一会，她也下来了，我俩并肩像操场走去，我曾在无数个日夜幻想这个场景。 起先我只是和她聊了下最近的生活，我太紧张了，这是我人生中第一次约女孩出来，也是我即将的第一次表白，我一直不能从话题中找一个契合的时机去表白，走着走着已经围绕操场走了2圈了，她也有点想回去的意思，我突然话锋一转，说最近好多人和你表白呀，里面有你喜欢的吗？她说目前还没有让她心动的，她突然也警觉起来，说了句：该不会你要向我表白吧，我从没考虑过和班上人谈恋爱。我赶紧红着脸回答道：不是的，我也才认识你不久，只是觉得你挺优秀...]]></description>
            <content:encoded><![CDATA[<p>如果世界上所有的表白都能成功的话，那这个世界就不会存在像我这样的人了。</p><p>      晚上我回到宿舍将我要表白她的事告诉了室友，室友纷纷当起了劝退师，觉得我压根配不上她，她有太多优质的选择。陷入爱河的我已经听不进任何人的劝阻了，只要有百分之零点一的机会我就想尝试下。于是接下来的几天我一直在计划我的表白了......       终于等到那天，今天的天气额外的宁静清爽，我以各种借口约她晚上去操场走走，起初她并不愿意，在我的死打烂缠下终于答应了。我提前买好了她喜欢的抹茶味奶茶，少糖。现在仍然记得等待时的心情，激动，紧张，充满期待，没一会，她也下来了，我俩并肩像操场走去，我曾在无数个日夜幻想这个场景。       起先我只是和她聊了下最近的生活，我太紧张了，这是我人生中第一次约女孩出来，也是我即将的第一次表白，我一直不能从话题中找一个契合的时机去表白，走着走着已经围绕操场走了2圈了，她也有点想回去的意思，我突然话锋一转，说最近好多人和你表白呀，里面有你喜欢的吗？她说目前还没有让她心动的，她突然也警觉起来，说了句：该不会你要向我表白吧，我从没考虑过和班上人谈恋爱。我赶紧红着脸回答道：不是的，我也才认识你不久，只是觉得你挺优秀的，想和你交个朋友而已....当时我裂了，铁铁们....       回到宿舍我强装着啥事没发生和他们说道表白延后了，我要充分准备下。半夜我哭了，没有声音，只是觉得心里很难受，甚至自己有点莫名其妙。       第一次表白就这样烂在了我心里，还有那封未送出的信。</p><p>                              ........       <em>我如果爱你</em> <em>绝不学攀援的凌霄花</em> <em>借你的高枝炫耀自己</em>       <em>我如果爱你</em> <em>绝不学痴情的鸟儿</em> <em>为绿荫重复单调的歌曲</em>                               ........</p><h1 id="h-promisepromise" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Promise用法及手写一个Promise</h1><h2 id="h-promise" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Promise 简介和基本用法</h2><p>promise 是一个拥有 <code>then</code> 方法的对象或函数，其行为符合本规范； promise A+规范我不会详细介绍,感兴趣的可以去promise官网了解。</p><p><code>then</code> 方法接受两个参数 <code>onFulfilled, onRejected</code> 。前者是成功的回调，后者是失败的回调。如果Promise里面执行的是resolve进入<code>onFulfilled</code>，执行reject进入<code>onRejected</code>。</p><p>人狠话不多，直接上干货了。</p><pre data-type="codeBlock" text="       new Promise((reslove, reject) =&gt; {
            console.log(1111);
            setTimeout(() =&gt; {
                console.log(&apos;setTimeut&apos;, 2222);
                reslove(1);
            }, 1000);
        }).then(
            (res) =&gt; {
                console.log(3333);
            },
            (err) =&gt; console.log(err),
        );
复制代码
"><code>       <span class="hljs-keyword">new</span> Promise((reslove, reject) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
            console.log(<span class="hljs-number">1111</span>);
            setTimeout(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                console.log(<span class="hljs-string">'setTimeut'</span>, <span class="hljs-number">2222</span>);
                reslove(<span class="hljs-number">1</span>);
            }, <span class="hljs-number">1000</span>);
        }).then(
            (res) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                console.log(<span class="hljs-number">3333</span>);
            },
            (err) <span class="hljs-operator">=</span><span class="hljs-operator">></span> console.log(err),
        );
复制代码
</code></pre><p>上图代码的执行结果如下：</p><p>Promise.all</p><p>使用场景：一次请求多个接口，需要同时拿到里面的信息。</p><p>接下来用promise结合setTimeout模拟axios</p><pre data-type="codeBlock" text="        var promise1 = Promise.resolve(&apos;我&apos;);
        var promise2 = new Promise(function(resolve, reject) {
            setTimeout(resolve, 1000, &apos;不是&apos;);
          });
        var promise3 = new Promise(function(resolve, reject) {
          setTimeout(resolve, 2000, &apos;舔狗&apos;);
        });
        Promise.all([promise1, promise2, promise3]).then(function(values) {
          console.log(values);
        }); 
复制代码
"><code>        <span class="hljs-keyword">var</span> promise1 <span class="hljs-operator">=</span> Promise.resolve(<span class="hljs-string">'我'</span>);
        <span class="hljs-keyword">var</span> promise2 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(resolve, <span class="hljs-number">1000</span>, <span class="hljs-string">'不是'</span>);
          });
        <span class="hljs-keyword">var</span> promise3 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resolve, reject</span>) </span>{
          setTimeout(resolve, <span class="hljs-number">2000</span>, <span class="hljs-string">'舔狗'</span>);
        });
        Promise.all([promise1, promise2, promise3]).then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">values</span>) </span>{
          console.log(values);
        }); 
复制代码
</code></pre><p>下图是values的打印结果</p><p>Promise.all 弊端</p><p>但Promise.all是有弊端的，假如你一次请求5个接口，只要有一个接口请求失败，他将会走到catch</p><pre data-type="codeBlock" text="        var promise1 = Promise.resolve(&apos;我&apos;);
        var promise2 = new Promise(function (resolve, reject) {
            setTimeout(reject, 1000, &apos;不是&apos;);
        });
        var promise3 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 2000, &apos;舔狗&apos;);
        });
        Promise.all([promise1, promise2, promise3])
            .then(function (values) {
                console.log(values);
            })
            .catch((err) =&gt; console.log(err));
复制代码
"><code>        <span class="hljs-keyword">var</span> promise1 <span class="hljs-operator">=</span> Promise.resolve(<span class="hljs-string">'我'</span>);
        <span class="hljs-keyword">var</span> promise2 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(reject, <span class="hljs-number">1000</span>, <span class="hljs-string">'不是'</span>);
        });
        <span class="hljs-keyword">var</span> promise3 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(resolve, <span class="hljs-number">2000</span>, <span class="hljs-string">'舔狗'</span>);
        });
        Promise.all([promise1, promise2, promise3])
            .then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">values</span>) </span>{
                console.log(values);
            })
            .catch((err) <span class="hljs-operator">=</span><span class="hljs-operator">></span> console.log(err));
复制代码
</code></pre><p>上面我把promise2 里面换成了reject，它走到catch，下图是打印的err</p><p>es11 的 Promise.allSettled 解决了Promise.all弊端</p><pre data-type="codeBlock" text="        var promise1 = Promise.resolve(&apos;我&apos;);
        var promise2 = new Promise(function (resolve, reject) {
            setTimeout(reject, 1000, &apos;不是&apos;);
        });
        var promise3 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 2000, &apos;舔狗&apos;);
        });
        Promise.allSettled([promise1, promise2, promise3])
            .then(function (values) {
                console.log(values);
            })
            .catch((err) =&gt; console.log(err));
复制代码
"><code>        <span class="hljs-keyword">var</span> promise1 <span class="hljs-operator">=</span> Promise.resolve(<span class="hljs-string">'我'</span>);
        <span class="hljs-keyword">var</span> promise2 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(reject, <span class="hljs-number">1000</span>, <span class="hljs-string">'不是'</span>);
        });
        <span class="hljs-keyword">var</span> promise3 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(resolve, <span class="hljs-number">2000</span>, <span class="hljs-string">'舔狗'</span>);
        });
        Promise.allSettled([promise1, promise2, promise3])
            .then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">values</span>) </span>{
                console.log(values);
            })
            .catch((err) <span class="hljs-operator">=</span><span class="hljs-operator">></span> console.log(err));
复制代码
</code></pre><p>无论是有失败的请求，他都会走到then里面，并用对象将结果包起来，下图是打印的values</p><p>Promise.race</p><p>多个请求中，那个先执行就返回该请求的结果，慢的就忽视了</p><pre data-type="codeBlock" text="        var promise2 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 1000, &apos;班花&apos;);
        });
        var promise3 = new Promise(function (resolve, reject) {
            setTimeout(resolve, 2000, &apos;舔狗&apos;);
        });
        Promise.all([ promise2, promise3])
            .then(function (values) {
                console.log(values);
            })
复制代码
"><code>        <span class="hljs-keyword">var</span> promise2 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(resolve, <span class="hljs-number">1000</span>, <span class="hljs-string">'班花'</span>);
        });
        <span class="hljs-keyword">var</span> promise3 <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">resolve, reject</span>) </span>{
            setTimeout(resolve, <span class="hljs-number">2000</span>, <span class="hljs-string">'舔狗'</span>);
        });
        Promise.all([ promise2, promise3])
            .then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">values</span>) </span>{
                console.log(values);
            })
复制代码
</code></pre><p>values的打印结果如下</p><p>Promise 值穿透 及如何中断Promise 链式请求</p><p>穿透</p><pre data-type="codeBlock" text="     Promise.resolve(1)
            .then(2) // 注意这里
            .then(Promise.resolve(3))
            .then(console.log);   // 输出1   这一步等同 .then((res)=&gt;{console.log(res)})
复制代码
"><code>     Promise.resolve(<span class="hljs-number">1</span>)
            .then(<span class="hljs-number">2</span>) <span class="hljs-comment">// 注意这里</span>
            .then(Promise.resolve(<span class="hljs-number">3</span>))
            .then(console.log);   <span class="hljs-comment">// 输出1   这一步等同 .then((res)=>{console.log(res)})</span>
复制代码
</code></pre><p>return 一个值修改下一个then里面的value</p><pre data-type="codeBlock" text="    Promise.resolve(1)
          .then(function(){return 2})
          .then(Promise.resolve(3))
          .then(console.log)  // 输出2
复制代码
"><code>    Promise.resolve(<span class="hljs-number">1</span>)
          .then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">return</span> <span class="hljs-number">2</span>})
          .then(Promise.resolve(<span class="hljs-number">3</span>))
          .then(console.log)  <span class="hljs-comment">// 输出2</span>
复制代码
</code></pre><pre data-type="codeBlock" text="    Promise.resolve(1)
          .then(function(){return 2})
          .then(function(){return Promise.resolve(3)})
          .then(console.log)  // 输出3
复制代码
"><code>    Promise.resolve(<span class="hljs-number">1</span>)
          .then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">return</span> <span class="hljs-number">2</span>})
          .then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{<span class="hljs-keyword">return</span> Promise.resolve(<span class="hljs-number">3</span>)})
          .then(console.log)  <span class="hljs-comment">// 输出3</span>
复制代码
</code></pre><p>如何中断Promise 中断Promise只有一种方法，那就是让他的状态变为pending Promise是有三种状态 <code>pending</code>，<code>fulfilled</code>，or <code>rejected</code></p><pre data-type="codeBlock" text="const promise = new Promise((resolve, reject) =&gt; {
        resolve(111);
    }).then((res)=&gt;{
        console.log(res)  //打印111
        return  2222
    }).then(res=&gt;{
        console.log(res)  //打印222
        return new Promise(()=&gt;{})
    }).then(res=&gt;{
        console.log(3333)  //不会打印，被中断了
    })
复制代码
"><code>const promise <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> Promise((resolve, reject) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
        resolve(<span class="hljs-number">111</span>);
    }).then((res)<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
        console.log(res)  <span class="hljs-comment">//打印111</span>
        <span class="hljs-keyword">return</span>  <span class="hljs-number">2222</span>
    }).then(res<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
        console.log(res)  <span class="hljs-comment">//打印222</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Promise(()<span class="hljs-operator">=</span><span class="hljs-operator">></span>{})
    }).then(res<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
        console.log(<span class="hljs-number">3333</span>)  <span class="hljs-comment">//不会打印，被中断了</span>
    })
复制代码
</code></pre><p>手写Promise</p><p>下图是我们常见的业务场景，由浅入深，我们先单纯的实现下面这个例子</p><pre data-type="codeBlock" text="    new Promise((resolve,reject)=&gt;{
            setTimeout(()=&gt;{
                console.log(1)
                resolve(2)
            },1000)
        }).then(res=&gt;{
            console.log(res)
        })
复制代码
"><code>    <span class="hljs-keyword">new</span> Promise((resolve,reject)<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
            setTimeout(()<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
                console.log(<span class="hljs-number">1</span>)
                resolve(<span class="hljs-number">2</span>)
            },<span class="hljs-number">1000</span>)
        }).then(res<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
            console.log(res)
        })
复制代码
</code></pre><p>是不是很简单，<code>x instanceof myPromise ? x.then(resolve, reject) : resolve(x);</code>就这行需要细品一下，如果卡在了setTimeout，可以看看事件循环机制，如果不懂class的可以看看我的第一文章</p><pre data-type="codeBlock" text="// 
const PENDING = &apos;pending&apos;;
const FULFILLED = &apos;fulfilled&apos;;
const REJECTED = &apos;rejected&apos;;

 class myPromise {
            constructor(executor) {
                let self = this;
                self.status = PENDING;
                self.value = undefined;
                self.reason = undefined;
                self.onResolvedCallbacks = [];
                self.onRejectedCallbacks = [];

                let resolve = (value) =&gt; {
                    if (self.status === PENDING) {
                        self.status = FULFILLED;
                        self.value = value;
                        self.onResolvedCallbacks.forEach((fn) =&gt; fn());
                    }
                };
                
                executor(resolve);
            }
        
            then(onFulfilled, onRejected) {
                let self=this
                 return new myPromise((resolve, reject) =&gt; {
                     if (self.status === &apos;pending&apos;) {
                        self.onResolvedCallbacks.push(() =&gt; {
                                let x = onFulfilled(self.value);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                        });
                        self.onRejectedCallbacks.push(() =&gt; {
                                let x = onRejected(self.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                        });
                      }
                  });
            }
        }
复制代码
"><code><span class="hljs-comment">// </span>
const PENDING <span class="hljs-operator">=</span> <span class="hljs-string">'pending'</span>;
const FULFILLED <span class="hljs-operator">=</span> <span class="hljs-string">'fulfilled'</span>;
const REJECTED <span class="hljs-operator">=</span> <span class="hljs-string">'rejected'</span>;

 class myPromise {
            <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">executor</span>) </span>{
                let <span class="hljs-built_in">self</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>;
                <span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span> PENDING;
                <span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> undefined;
                <span class="hljs-built_in">self</span>.reason <span class="hljs-operator">=</span> undefined;
                <span class="hljs-built_in">self</span>.onResolvedCallbacks <span class="hljs-operator">=</span> [];
                <span class="hljs-built_in">self</span>.onRejectedCallbacks <span class="hljs-operator">=</span> [];

                let resolve <span class="hljs-operator">=</span> (value) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> PENDING) {
                        <span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span> FULFILLED;
                        <span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> value;
                        <span class="hljs-built_in">self</span>.onResolvedCallbacks.forEach((fn) <span class="hljs-operator">=</span><span class="hljs-operator">></span> fn());
                    }
                };
                
                executor(resolve);
            }
        
            then(onFulfilled, onRejected) {
                let <span class="hljs-built_in">self</span><span class="hljs-operator">=</span><span class="hljs-built_in">this</span>
                 <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> myPromise((resolve, reject) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                     <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'pending'</span>) {
                        <span class="hljs-built_in">self</span>.onResolvedCallbacks.<span class="hljs-built_in">push</span>(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                                let x <span class="hljs-operator">=</span> onFulfilled(<span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span>);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                        });
                        <span class="hljs-built_in">self</span>.onRejectedCallbacks.<span class="hljs-built_in">push</span>(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                                let x <span class="hljs-operator">=</span> onRejected(<span class="hljs-built_in">self</span>.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                        });
                      }
                  });
            }
        }
复制代码
</code></pre><p>下图我加入了reject，也完善了then方法里面当状态位fulfilled和rejected。代码量其实并不多....</p><pre data-type="codeBlock" text="    const PENDING = &apos;pending&apos;;
    const FULFILLED = &apos;fulfilled&apos;;
    const REJECTED = &apos;rejected&apos;;
     class myPromise {
            constructor(executor) {
                let self = this;
                self.status = PENDING;
                self.value = undefined;
                self.reason = undefined;
                self.onResolvedCallbacks = [];
                self.onRejectedCallbacks = [];

                let resolve = (value) =&gt; {
                    if (self.status === PENDING) {
                        self.status = FULFILLED;
                        self.value = value;
                        self.onResolvedCallbacks.forEach((fn) =&gt; fn());
                    }
                };

                let reject = (reason) =&gt; {
                    if (self.status === PENDING) {
                        self.status = REJECTED;
                        self.reason = reason;
                        self.onRejectedCallbacks.forEach((fn) =&gt; fn());
                    }
                };
                try {
                    executor(resolve, reject);
                } catch {
                    reject(err);
                }
            }

            then(onFulfilled, onRejected) {
                //处理then里面不是回调函数情况
                //Promise/A+ 2.2.1 / Promise/A+ 2.2.5 / Promise/A+ 2.2.7.3 / Promise/A+ 2.2.7.4
                onFulfilled = typeof onFulfilled === &apos;function&apos; ? onFulfilled : (v) =&gt; v;
                onRejected =
                    typeof onRejected === &apos;function&apos;
                        ? onRejected
                        : (err) =&gt; {
                              throw err;
                          };
                let self = this;
                return new myPromise((resolve, reject) =&gt; {
                    if (self.status === &apos;fulfilled&apos;) {
                        setTimeout(() =&gt; {
                            try {
                                let x = onFulfilled(self.value);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            } catch (err) {
                                reject(err);
                            }
                        }, 0);
                    }
                    if (self.status === &apos;rejected&apos;) {
                        setTimeout(() =&gt; {
                            try {
                                let x = onRejected(self.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            } catch (err) {
                                reject(err);
                            }
                        }, 0);
                    }
                    if (self.status === &apos;pending&apos;) {
                        self.onResolvedCallbacks.push(() =&gt; {
                            setTimeout(() =&gt; {
                                let x = onFulfilled(self.value);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            }, 0);
                        });
                        self.onRejectedCallbacks.push(() =&gt; {
                            setTimeout(() =&gt; {
                                let x = onRejected(self.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            }, 0);
                        });
                    }
                });
            }
        }
复制代码
"><code>    const PENDING <span class="hljs-operator">=</span> <span class="hljs-string">'pending'</span>;
    const FULFILLED <span class="hljs-operator">=</span> <span class="hljs-string">'fulfilled'</span>;
    const REJECTED <span class="hljs-operator">=</span> <span class="hljs-string">'rejected'</span>;
     class myPromise {
            <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">executor</span>) </span>{
                let <span class="hljs-built_in">self</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>;
                <span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span> PENDING;
                <span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> undefined;
                <span class="hljs-built_in">self</span>.reason <span class="hljs-operator">=</span> undefined;
                <span class="hljs-built_in">self</span>.onResolvedCallbacks <span class="hljs-operator">=</span> [];
                <span class="hljs-built_in">self</span>.onRejectedCallbacks <span class="hljs-operator">=</span> [];

                let resolve <span class="hljs-operator">=</span> (value) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> PENDING) {
                        <span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span> FULFILLED;
                        <span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> value;
                        <span class="hljs-built_in">self</span>.onResolvedCallbacks.forEach((fn) <span class="hljs-operator">=</span><span class="hljs-operator">></span> fn());
                    }
                };

                let reject <span class="hljs-operator">=</span> (reason) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> PENDING) {
                        <span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span> REJECTED;
                        <span class="hljs-built_in">self</span>.reason <span class="hljs-operator">=</span> reason;
                        <span class="hljs-built_in">self</span>.onRejectedCallbacks.forEach((fn) <span class="hljs-operator">=</span><span class="hljs-operator">></span> fn());
                    }
                };
                <span class="hljs-keyword">try</span> {
                    executor(resolve, reject);
                } <span class="hljs-keyword">catch</span> {
                    reject(err);
                }
            }

            then(onFulfilled, onRejected) {
                <span class="hljs-comment">//处理then里面不是回调函数情况</span>
                <span class="hljs-comment">//Promise/A+ 2.2.1 / Promise/A+ 2.2.5 / Promise/A+ 2.2.7.3 / Promise/A+ 2.2.7.4</span>
                onFulfilled <span class="hljs-operator">=</span> typeof onFulfilled <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'function'</span> ? onFulfilled : (v) <span class="hljs-operator">=</span><span class="hljs-operator">></span> v;
                onRejected <span class="hljs-operator">=</span>
                    typeof onRejected <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'function'</span>
                        ? onRejected
                        : (err) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                              <span class="hljs-keyword">throw</span> err;
                          };
                let <span class="hljs-built_in">self</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>;
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> myPromise((resolve, reject) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'fulfilled'</span>) {
                        setTimeout(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                            <span class="hljs-keyword">try</span> {
                                let x <span class="hljs-operator">=</span> onFulfilled(<span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span>);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            } <span class="hljs-keyword">catch</span> (err) {
                                reject(err);
                            }
                        }, <span class="hljs-number">0</span>);
                    }
                    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'rejected'</span>) {
                        setTimeout(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                            <span class="hljs-keyword">try</span> {
                                let x <span class="hljs-operator">=</span> onRejected(<span class="hljs-built_in">self</span>.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            } <span class="hljs-keyword">catch</span> (err) {
                                reject(err);
                            }
                        }, <span class="hljs-number">0</span>);
                    }
                    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">self</span>.status <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'pending'</span>) {
                        <span class="hljs-built_in">self</span>.onResolvedCallbacks.<span class="hljs-built_in">push</span>(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                            setTimeout(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                                let x <span class="hljs-operator">=</span> onFulfilled(<span class="hljs-built_in">self</span>.<span class="hljs-built_in">value</span>);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            }, <span class="hljs-number">0</span>);
                        });
                        <span class="hljs-built_in">self</span>.onRejectedCallbacks.<span class="hljs-built_in">push</span>(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                            setTimeout(() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                                let x <span class="hljs-operator">=</span> onRejected(<span class="hljs-built_in">self</span>.reason);
                                x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
                            }, <span class="hljs-number">0</span>);
                        });
                    }
                });
            }
        }
复制代码
</code></pre><p>仔细分析下<code>onFulfilled = typeof onFulfilled === &apos;function&apos; ? onFulfilled : (v) =&gt; v;</code> 和 <code>let x = onFulfilled(self.value);</code>，你就知道下图为啥是这个结果了</p><p>Promise.resolve</p><p>太简单了吧</p><pre data-type="codeBlock" text="    static resolve(data){ 
        return new Promise((resolve,reject)=&gt;{ resolve(data); }) 
    }
复制代码
"><code>    <span class="hljs-keyword">static</span> <span class="hljs-title function_">resolve</span>(<span class="hljs-params">data</span>){ 
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve,reject</span>)=></span>{ <span class="hljs-title function_">resolve</span>(data); }) 
    }
复制代码
</code></pre><p>Promise.all</p><p>promise.race我就不写了，大家可以参考all想想如何实现</p><pre data-type="codeBlock" text="    static all(values) {
            if (!Array.isArray(values)) {
              return new TypeError(&quot;请输入一个数组&quot;)
            }
            return new Promise((resolve, reject) =&gt; {
              let resultArr = [];
              let len = 0;
              const dealFn = (value, index) =&gt; {
                resultArr[index] = value;
                if (++len === values.length) {
                    resolve(resultArr)
                }
              }
              for (let i = 0; i &lt; values.length; i++) {
                let value = values[i];
                //判断value是否还是个promise
                if (value &amp;&amp; typeof value.then === &apos;function&apos;) {
                  value.then((value) =&gt; {
                    dealFn(value, i);
                  }, reject);
                } else {
                    dealFn(value, i);
                }
              }
            });
          }
复制代码
"><code>    static all(values) {
            <span class="hljs-keyword">if</span> (<span class="hljs-operator">!</span>Array.isArray(values)) {
              <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TypeError(<span class="hljs-string">"请输入一个数组"</span>)
            }
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Promise((resolve, reject) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
              let resultArr <span class="hljs-operator">=</span> [];
              let len <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
              const dealFn <span class="hljs-operator">=</span> (value, index) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                resultArr[index] <span class="hljs-operator">=</span> value;
                <span class="hljs-keyword">if</span> (<span class="hljs-operator">+</span><span class="hljs-operator">+</span>len <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> values.<span class="hljs-built_in">length</span>) {
                    resolve(resultArr)
                }
              }
              <span class="hljs-keyword">for</span> (let i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> values.<span class="hljs-built_in">length</span>; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
                let value <span class="hljs-operator">=</span> values[i];
                <span class="hljs-comment">//判断value是否还是个promise</span>
                <span class="hljs-keyword">if</span> (value <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> typeof value.then <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'function'</span>) {
                  value.then((value) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                    dealFn(value, i);
                  }, reject);
                } <span class="hljs-keyword">else</span> {
                    dealFn(value, i);
                }
              }
            });
          }
复制代码
</code></pre><p>总结</p><p>我用setTimeout模拟去实现它的延迟执行，没有过多的处理promise整体的容错性，真实的源码用了大量的回调去处理异步执行问题，我只是实现了Promise的回调思想。如果想深入学习Promise的可以去看看官网，我已经晕倒在里面了。只要你认真读懂以上内容，至少不会担心面试官问你promise了</p>]]></content:encoded>
            <author>gregoria@newsletter.paragraph.com (Gregoria)</author>
        </item>
        <item>
            <title><![CDATA[AMA content]]></title>
            <link>https://paragraph.com/@gregoria/ama-content</link>
            <guid>vZwaaBA8gCYL9qqHJIyF</guid>
            <pubDate>Mon, 08 Nov 2021 02:27:58 GMT</pubDate>
            <description><![CDATA[HTTP状态码及其含义1xx: 信息状态码 100：继续，一般在post请求，服务器接收到header，然后返回状态，然后继续发送具体参数 2xx： 成功状态码 200：请求成功 201：请求成功，并且服务器创建了新的资源 202：请求已被接收，但尚未被处理 3xx: 重定向 301：资源已经永久移动到新位置 302：临时重定向 303：临时重定向，且总是使用get请求新的URI 304：自从上次请求后，请求的网页未发生修改 4xx： 客户端错误 400：服务器无法理解请求的格式，客户端应当不在用此内容发起请求 401：请求未授权 403：拒绝访问 404：请求的URI不存在或者内容已经删除，无法匹配到资源 5xx 500：服务器内部的错误 501：服务器暂时无法处理请求，可能是过载或维护HTML5新特性新增标签：section，aside，article，header，footer，nav… 媒体：video，audio 绘图：Canvas(js绘2D图)，SVG(XML描述2D图形语言) 表单控件input的type属性：url，number，email，search，tim...]]></description>
            <content:encoded><![CDATA[<h4 id="h-http" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">HTTP状态码及其含义</h4><p><strong>1xx:</strong> 信息状态码 100：继续，一般在post请求，服务器接收到header，然后返回状态，然后继续发送具体参数</p><p><strong>2xx：</strong> 成功状态码 200：请求成功 201：请求成功，并且服务器创建了新的资源 202：请求已被接收，但尚未被处理</p><p><strong>3xx:</strong> 重定向 301：资源已经永久移动到新位置 302：临时重定向 303：临时重定向，且总是使用get请求新的URI 304：自从上次请求后，请求的网页未发生修改</p><p><strong>4xx：</strong> 客户端错误 400：服务器无法理解请求的格式，客户端应当不在用此内容发起请求 401：请求未授权 403：拒绝访问 404：请求的URI不存在或者内容已经删除，无法匹配到资源</p><p><strong>5xx</strong> 500：服务器内部的错误 501：服务器暂时无法处理请求，可能是过载或维护</p><h4 id="h-html5" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">HTML5新特性</h4><p>新增标签：section，aside，article，header，footer，nav…</p><p>媒体：video，audio</p><p>绘图：Canvas(js绘2D图)，SVG(XML描述2D图形语言)</p><p>表单控件input的type属性：url，number，email，search，time，color，week，month…</p><p>新的技术：WebWorker(将数据较大的任务给子线程，子线程处理好之后返回给主线程)，WebSocket(全双工通讯)，拖放API，WebStorage(localStorage,sessionStorage)</p>]]></content:encoded>
            <author>gregoria@newsletter.paragraph.com (Gregoria)</author>
        </item>
    </channel>
</rss>