警告
请勿将此软件包作为依赖关系安装! (请参阅:入门)
当前,承诺是处理JavaScript中异步任务的事实上的方式,因此,它们是任何JavaScript开发人员知识的基本组成部分。
但是,当我们第一次学习的承诺时,我们只学会了足够的学习,即,我们学到了一些如何使用承诺(如今,最有可能仅使用async/await ), Promise.all Method。就是这样。
尽管这种方法对初学者来说是有意义的,因为它足以解决他们日常生活中的大多数问题,但反复出现的问题是,他们停在那里,也就是说,他们永远不会超越最初的知识。
正是这种“学到足以获得”的姿势,使许多开发人员处于目前的水平,因为解决更复杂的问题需要更深入的了解。
因此,如果您想将开发人员的技能提升到一个新的水平,在浅水中游泳不会削减它,您必须更深入地,您需要完全了解承诺以及如何工作,您需要精通async/await / then/catch promise的承诺处理方式,并能够以最有效的方式解决异步的任务。
同样,由于承诺最终是处理异步任务的抽象,因此必须解决与异步编程有关的常见问题。
考虑到这一点,我们精确地创建了这个项目,以帮助您深入了解诺言和异步编程。
通过提供围绕这些主题的解释和实践练习,该项目旨在成为您掌握这些主题的同伴。
即使您已经是经验丰富的开发人员,您也可能会学到一两件事,例如,您可能想尝试解决concrete/parallelMaxConcurrency , concrete/concurrencyOverride , concrete/extractingResolvers和/foundation/promise因为它们带来了一些有趣的挑战。
重要的
该项目并非针对第一次学习承诺的人,因为它假设您至少对承诺,他们所代表的内容以及如何使用async/await和then/catch有一些基本知识。
警告
注意:除非您是最终用户,否则此存储库不应被克隆
首先,要安装项目,运行:
npm create promises-training@latest笔记
该项目是锻炼驱动的,因此主要目标是解决它们。
有时,会有解释以及练习,以帮助您了解需要做的事情,以及有关解决问题的背景。
练习分为三类:
重要的
没有针对类别的特定顺序,您可以从其中任何一个开始,甚至可以在完全完成另一个类别之前切换到另一个类别。但是,练习的级别不同,接下来将讨论。
练习位于src/exercises/<category>文件夹中,其中<category>是上面提到的类别之一。
对于图形练习,基本解释位于此读数中,在图表部分中,对于每个练习,都有一个graph.png描绘了该特定练习的依赖关系图。
对于混凝土和粉底练习,解释位于练习夹内的README.md中(例如src/exercises/concrete/parallelChunks/README.md )。
要解决练习,您需要编辑src/exercises/<category>/<exercise>/exercise.ts文件。
解决练习后,您可以通过运行检查解决方案:
npm run check < category > / < exercise >测试位于src/tests中。
通常,您只会在练习文件夹中工作,因为设计测试的方式可以告诉您不必查看其实现的问题,但是如果出于任何原因,您可能会陷入困境或好奇,则可以窥视它们。
src/lib文件夹仅用于内部用途,因此请勿打扰它。
另外,要使安装向前与未来版本兼容,请勿修改src/exercises文件夹之外的任何文件。
除类别外,练习还分为水平,在您通过级别进行时,练习的难度会增加。
有三个级别:
请记住,此分类有些主观,因此YMMV,您也不一定需要在一个水平上完成所有练习才能移至下一个练习。
笔记
如您所见,目前没有太多的高级练习,但是想法是随着时间的推移将添加新的练习。
每个练习都伴随自动测试,因此您可以检查解决方案。
要运行一个练习的测试,请运行:
npm run check < category > / < exercise >例如,要运行parallelChunks练习的测试,请运行:
npm run check concrete/parallelChunks或者,要运行图2号练习,请运行:
npm run check graph/2/test.test.ts笔记
在上一个示例中,我们需要将/test.test.ts附加到练习文件上,否则它也将用于以2开头的其他图形练习运行,例如:练习2至29。
我们将Vitest用作测试跑者,因此所有CLI选项均可使用。
同样,重要的是要提到,图形练习具有一些特殊性,因为它们是从图本身自动生成的,因此,有些练习有大量的测试(某些练习具有超过100K测试)。
当然,我们不会运行所有这些,因为它会非常慢,因此我们只运行其中的一个子集,并且可以调整运行的测试数量和子集的测试数量。
您可以在“图形练习”部分中阅读更多内容。
目前,有三个运动类别:
处理异步任务的很大一部分是策划它们,以便每个任务尽快启动,并正确协调这些任务,我们需要了解它们之间的依赖关系。
在此类别中,您将在每个练习中都有一个依赖图,然后您将以最有效的方式在图中进行任务。
由于练习专注于编排本身,因此通过调用createPromise(label)创建任务,其中label是标识任务的字符串。
以此图为例:

该图中有两个任务, A和B , B取决于A ,该任务由从B出来并指向A箭头表示。
这意味着B只有在A完成后才开始,并且A (不取决于任何其他任务)可以立即开始。
因此,该图最有效的实现将是:
await createPromise ( "A" ) ;
await createPromise ( "B" ) ;任务还可以取决于多个任务:

在此图中, C取决于A和B ,因此只有在A和B完成后才可以启动。
但是, A和B都不依赖于任何其他任务,因此它们可以立即开始。
该图最有效的实现将是:
await Promise . all ( [ createPromise ( "A" ) , createPromise ( "B" ) ] ) ;
await createPromise ( "C" ) ;任务还可以具有多个不同的依赖关系集,如果满足任何集合,则可以启动任务:

在此图中, C取决于A或B上,该图是通过为每个依赖关系集使用不同颜色表示的。颜色本身没有任何特定的含义,它们像这样使用了,因此依赖关系彼此区分。
因此, C可以在A或B完成后立即开始。
await Promise . any ( [ createPromise ( "A" ) , createPromise ( "B" ) ] ) ;
await createPromise ( "C" ) ;最后但并非最不重要的一点是,承诺有两个可能的结果:可以实现或拒绝。

在此图中,我们的任务B取决于A的满足和任务C ,取决于A的拒绝。
重要的
虚线边缘用于表示承诺拒绝。
这意味着B只有在实现A后才开始,并且C只有在A拒绝后才能开始。
由于可能只有这些结果之一,因此B或C将进行。
相应的实现:
try {
await createPromise ( "A" ) ;
try {
await createPromise ( "B" ) ;
} catch { }
} catch {
await createPromise ( "C" ) ;
}进行图形练习时,您会注意到三个功能正在导出: mixed , asyncAwait , thenCatch 。
这个想法是为您提供3种不同的实现:
mixed :这是完全免费的,您可以混合异步/等待,然后/捕获asyncAwait :在此中,您应该只使用异步/等待thenCatch :在此中,您只应使用/捕获。这样,您将精通两种承诺处理方式。
另外,在文件的末尾,您会注意到出口被包裹在skipExercise中,该skipecercise跳过了该特定实现的测试,以免输出输出。
当您为这三个方面实现解决方案时,请删除要运行测试的实现的skipExercise调用。例如:如果您已经实施了mixed解决方案,请从中删除skipExercise ,但将其保留为asyncAwait和thenCatch直到实现它们为止。
为了帮助您调试图形练习的实现,我们创建了一个UI,允许您模拟不同的执行“路径”。
要打开UI,请运行:
npm run graph:uiUI用作网络应用程序,看起来像这样。

现在让我们探索每个部分:

左侧的侧边栏使您可以选择要调试的练习。

此顶部部分允许您选择要调试的实现。

右侧栏可让您通过解决/拒绝承诺来控制练习的执行流。
由于创建了承诺,侧边栏中添加了新条目。

中心的本节显示了在每个步骤中创建和解决/拒绝的承诺的记录。

底部的本节显示了按顺序解决/拒绝的承诺的摘要。
由于图形练习是基于图形(DUH)的,因此可以自动为给定练习生成所有可能的测试,这就是我们要做的。
正如人们可能想象的那样,生成的测试的数量有时很大,因此我们在运行的最大测试数量上有一个上限。
另外,为了防止偏见,我们不会按照生成的顺序进行测试,而是将其洗牌。
这种改组会在测试首次生成之后就会发生,因此测试是确定性的,也就是说,每次运行图形练习测试时,您都会运行相同的测试子集。
但是,可以调整运行的测试的盖子和子集。
要调整帽子,您可以运行npm run graph:setGraphTestsCap <number> 。
例如,要将上限设置为10000,请运行:
npm run graph:setGraphTestsCap 10000要调整运行的测试子集,您可以运行npm run graph:shuffleGraphTestData <graph-exercise-number> ,它将改组指定的图形练习的测试,然后导致不同的测试子集。
例如,为了重新填充图2的图表测试,请运行:
npm run graph:shuffleGraphTestData 2图形练习非常适合理解任务之间的依赖关系,但是,它们并不能涵盖可能的方案的完整范围,因为只有其依赖关系在编译时已知并且固定的任务可以由图表表示。
因此,我们有这种类别的具体练习,您将为您提供必须实现的具体场景。
由于此类别中的每个练习都是独一无二的,因此它们的描述与文件夹共归入。
基础练习旨在通过重新实现与承诺相关的职能以及最终的承诺本身来帮助您加强对承诺基础的理解。
描述与练习一起进行。
练习的解决方案可以在此仓库中找到,例如https://github.com/henriqueinonhe/promises-training/blob/master/src/src/exercises/concrete/concrete/concurrencyabort/exercise.ts。
但是,我们建议您自己解决练习后仅检查解决方案,因为目标是通过解决练习来学习。
另外,请记住,目前提出的解决方案不一定是最好的解决方案,这意味着即使您的解决方案根本不像您在这里找到的解决方案,也不意味着它们是不好的。
为了简化升级到新版本,我们创建了一个迁移脚本,该脚本将您的安装自动迁移到最新版本,同时保留解决方案。
要运行迁移脚本,请运行:
npm create promises-training@latest -- --migrate该项目已根据CC-BY-NC-ND 4.0许可。
该项目背后的目标是成为免费的学习资源,并使其永远保持自由且可访问。
这是有关许可证的一些常见问题的问答:
我可以使用这个项目进行自我研究吗?
是的,请这样做。
我可以在内部公司培训中使用这个项目吗?
是的,只要您相信该项目,并明确该项目独立于培训就可以自由访问。
我可以将这个项目用于我的付费指导/研讨会会议吗?
是的,只要您归功于该项目,请明确指出该项目独立于指导/研讨会独立于自由访问,请清楚地表明,您正在为您的时间而不是为项目本身充电,请清楚地表明该项目不是您自己的材料的一部分,并明确表明我们不认可您或您的服务。
我可以将这个项目用于我的付费在线课程吗?
是的,只要您归功于该项目,请明确指出该项目独立于在线课程上可以自由访问,请清楚地表明您是在收费,而不是为项目本身收费,请清楚地表明,该项目不是您自己的材料的一部分,并明确表示我们不认可您或您的服务。
我可以创建该项目的叉子并将其用于我自己的目的吗?
不,你不能。您只能按原样使用此项目,而无需任何修改。这是防止人们创建叉子然后为他们收取费用的必要条件。
我可以根据这个项目创建在线课程吗?
不,您不能,因为我们不希望人们围绕这个项目创建“包装纸”,然后为他们收费。
如果您对许可证有任何疑问,或想谈论特定用例,请随时通过[email protected]与我联系。