คำเตือน
อย่าติดตั้งแพ็คเกจนี้เป็นการพึ่งพา! (ดู: เริ่มต้น)
ปัจจุบันสัญญาเป็นวิธีการจัดการงานแบบอะซิงโครนัสใน JavaScript และด้วยเหตุนี้พวกเขาจึงเป็นส่วนพื้นฐานของความรู้ของนักพัฒนาจาวาสคริปต์
อย่างไรก็ตามเมื่อเราเรียนรู้สัญญาเป็นครั้งแรกเราเรียนรู้ เพียงพอที่จะผ่านไปได้ นั่นคือเราเรียนรู้วิธีการใช้สัญญาเล็กน้อย (ทุกวันนี้น่าจะเป็น async/await เพียง) วิธี Promise.all ทั้งหมดและนั่นคือ
ในขณะที่วิธีการนี้เหมาะสมสำหรับผู้เริ่มต้นเพราะมันเพียงพอที่จะแก้ปัญหาส่วนใหญ่ในชีวิตประจำวันของพวกเขาปัญหาที่เกิดขึ้นอีกคือพวกเขา หยุดอยู่ที่ นั่นนั่นคือพวกเขาไม่เคยผ่านความรู้เริ่มต้นนี้
และนี่เป็นสิ่งที่ "เรียนรู้เพียงพอที่จะได้รับ" ท่าทางที่มีนักพัฒนาหลายคนในระดับปัจจุบันของพวกเขาเนื่องจากการแก้ปัญหาที่ซับซ้อนมากขึ้นต้องมีความเข้าใจที่ลึกซึ้งยิ่งขึ้น
ดังนั้นหากคุณต้องการนำทักษะนักพัฒนาของคุณไปสู่ อีกระดับ การว่ายน้ำในน่านน้ำตื้น จะไม่ตัดมัน คุณ จะต้องลึกลงไป คุณต้องเข้าใจคำสัญญาอย่างเต็มที่และวิธีการทำงานของพวกเขาคุณต้องมีความเชี่ยวชาญทั้งใน async/await then/catch
นอกจากนี้ตามที่สัญญาเป็นสิ่งที่เป็นนามธรรมในการจัดการงานแบบอะซิงโครนัสทำให้สามารถจัดการกับปัญหาทั่วไปที่เกี่ยวข้องกับการเขียนโปรแกรมแบบอะซิงโครนัสเป็นสิ่งจำเป็น
โดยที่ในใจเราจึงสร้างโครงการนี้อย่างแม่นยำเพื่อช่วยให้คุณทำการดำน้ำลึกลงไปในคำสัญญาและการเขียนโปรแกรมแบบอะซิงโครนัส
ด้วยการให้ทั้งคำอธิบายและแบบฝึกหัดเชิงปฏิบัติโดยรอบหัวข้อเหล่านี้โครงการนี้มีจุดมุ่งหมายที่จะเป็นเพื่อนของคุณในการเดินทางครั้งนี้เพื่อเชี่ยวชาญ
แม้ว่าคุณจะเป็นนักพัฒนาที่มีประสบการณ์อยู่แล้วคุณอาจเรียนรู้สิ่งหนึ่งหรือสองอย่างเช่นคุณอาจต้องการลองแก้ concrete/parallelMaxConcurrency , concrete/concurrencyOverride , concrete/extractingResolvers /foundation/promise
สำคัญ
โครงการนี้ไม่ได้มีไว้สำหรับผู้ที่กำลังเรียนรู้สัญญาเป็นครั้งแรกเนื่องจากสมมติว่าคุณมีความรู้พื้นฐานเกี่ยวกับคำสัญญาอย่างน้อยสิ่งที่พวกเขาเป็นตัวแทนและวิธีการใช้พวกเขาทั้งสองกับ async/await และ then/catch
คำเตือน
ความสนใจ: repo นี้ไม่ได้หมายถึงการโคลนเว้นแต่คุณจะมีส่วนร่วมหากคุณเป็นผู้ใช้ปลายทางโปรดทำตามคำแนะนำด้านล่าง
ก่อนอื่นในการติดตั้งโครงการรัน:
npm create promises-training@latestบันทึก
โครงการนี้ขับเคลื่อนด้วยการออกกำลังกายดังนั้นเป้าหมายหลักคือการแก้ปัญหา
บางครั้งจะมีคำอธิบายพร้อมกับแบบฝึกหัดเพื่อช่วยให้คุณเข้าใจสิ่งที่ต้องทำและบริบทบางอย่างเกี่ยวกับปัญหาที่ได้รับการแก้ไข
แบบฝึกหัดแบ่งออกเป็นสามประเภท:
สำคัญ
ไม่มีคำสั่งซื้อเฉพาะสำหรับหมวดหมู่คุณสามารถเริ่มต้นจากใด ๆ และเปลี่ยนไปใช้อีกรายการหนึ่งก่อนที่จะเสร็จสิ้นอีกอันหนึ่งอย่างสมบูรณ์ อย่างไรก็ตามแบบฝึกหัดมีระดับที่แตกต่างกันซึ่งจะกล่าวถึงต่อไป
แบบฝึกหัดอยู่ในโฟลเดอร์ src/exercises/<category> โดยที่ <category> เป็นหนึ่งในหมวดหมู่ที่กล่าวถึงข้างต้น
สำหรับแบบฝึกหัด กราฟ คำอธิบายพื้นฐานจะอยู่ใน readme นี้ในส่วนกราฟและสำหรับการออกกำลังกายแต่ละครั้งจะมี 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 และคุณไม่จำเป็นต้องออกกำลังกายทั้งหมดในระดับที่จะย้ายไปยังอีก
บันทึก
อย่างที่คุณเห็นในปัจจุบันมีแบบฝึกหัดขั้นสูงไม่มากนัก แต่แนวคิดก็คือการออกกำลังกายใหม่จะถูกเพิ่มเมื่อเวลาผ่านไป
การออกกำลังกายแต่ละครั้งจะมาพร้อมกับการทดสอบอัตโนมัติเพื่อให้คุณสามารถตรวจสอบโซลูชันของคุณได้
ในการเรียกใช้การทดสอบแบบฝึกหัดเดียว Run:
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 : อันนี้ฟรีอย่างสมบูรณ์คุณสามารถผสมทั้งสอง async/รอและจากนั้น/จับasyncAwait : ในอันนี้คุณควรใช้ Async/รอคอยthenCatch : ในอันนี้คุณควรใช้/จับเท่านั้นวิธีนี้คุณจะมีความเชี่ยวชาญในการจัดการสัญญาทั้งสองรูปแบบ
นอกจากนี้ในตอนท้ายของไฟล์คุณจะสังเกตเห็นว่าการส่งออกกำลังถูกห่อหุ้มด้วย skipExercise ซึ่งข้ามการทดสอบสำหรับการใช้งานที่เฉพาะเจาะจงนั้นเพื่อไม่ให้ส่งผลออก
ในขณะที่คุณใช้โซลูชันสำหรับแต่ละสามนั้นให้ลบการโทร skipExercise สำหรับการใช้งานที่คุณต้องการให้การทดสอบทำงาน ตัวอย่างเช่น: หากคุณใช้โซลูชัน mixed แล้วให้ลบ skipExercise ออกจากมัน แต่เก็บสิ่งเหล่านี้ไว้สำหรับ asyncAwait และ thenCatch จนกว่าคุณจะนำไปใช้
เพื่อช่วยคุณในการดีบักการใช้งานของคุณสำหรับแบบฝึกหัดกราฟเราได้สร้าง UI ที่ช่วยให้คุณจำลองการดำเนินการ "เส้นทาง" ที่แตกต่างกัน
เพื่อเปิด UI, Run:
npm run graph:uiUI ทำหน้าที่เป็นเว็บแอปและดูเหมือนว่า

ตอนนี้เรามาสำรวจแต่ละส่วนกันเถอะ:

แถบด้านข้างทางด้านซ้ายช่วยให้คุณเลือกแบบฝึกหัดที่คุณต้องการแก้ไขข้อบกพร่อง

ส่วนบนสุดนี้ช่วยให้คุณสามารถเลือกการใช้งานที่คุณต้องการแก้ไขข้อบกพร่อง

แถบด้านข้างขวาช่วยให้คุณควบคุมการดำเนินการของการออกกำลังกายโดยการแก้ไข/ปฏิเสธสัญญา
ตามสัญญาถูกสร้างขึ้นรายการใหม่จะถูกเพิ่มเข้าไปในแถบด้านข้าง

ส่วนนี้ที่ศูนย์แสดงบันทึกของสัญญาที่สร้างและแก้ไข/ปฏิเสธในแต่ละขั้นตอน

ส่วนนี้ที่ด้านล่างแสดงบทสรุปของสัญญาที่ได้รับการแก้ไข/ปฏิเสธในแต่ละขั้นตอนตามลำดับ
เนื่องจากแบบฝึกหัดกราฟขึ้นอยู่กับกราฟ (DUH) เป็นไปได้ที่จะสร้าง การทดสอบที่เป็นไปได้ทั้งหมด สำหรับการออกกำลังกายที่กำหนดโดยอัตโนมัติซึ่งเป็นสิ่งที่เราทำ
อย่างที่ใคร ๆ ก็จินตนาการว่าจำนวนการทดสอบที่สร้างขึ้นบางครั้งมีขนาดใหญ่มากดังนั้นเรา จึง มีจำนวนการทดสอบสูงสุดที่เรียกใช้
นอกจากนี้เพื่อป้องกันอคติเราไม่ได้ทำการทดสอบตามลำดับที่พวกเขาถูกสร้างขึ้นแทนเรา สลับ พวกเขา
การสับเปลี่ยนครั้งนี้เกิดขึ้นทันทีหลังจากการทดสอบถูกสร้างขึ้นครั้งแรกดังนั้นการทดสอบจะ ถูกกำหนด นั่นคือทุกครั้งที่คุณทำการทดสอบแบบฝึกหัดกราฟคุณจะทำการทดสอบ ชุด ย่อยเดียวกัน
อย่างไรก็ตามมันเป็นไปได้ที่จะ ปรับแต่ง ทั้ง หมวก และ ชุดย่อย ของการทดสอบที่ทำงาน
ในการปรับแต่งฝาครอบคุณสามารถเรียกใช้ npm run graph:setGraphTestsCap <number>
ตัวอย่างเช่นในการตั้งค่าหมวกเป็น 10,000 ให้เรียกใช้:
npm run graph:setGraphTestsCap 10000 ในการปรับแต่งชุดย่อยของการทดสอบที่เรียกใช้คุณสามารถเรียกใช้ npm run graph:shuffleGraphTestData <graph-exercise-number> ออกกำลังกาย-หมายเลข> ซึ่งจะสับเปลี่ยนการทดสอบสำหรับแบบฝึกหัดกราฟที่ระบุซึ่งจะส่งผลให้ชุดทดสอบย่อยแตกต่างกัน
ตัวอย่างเช่นการสับเปลี่ยนการทดสอบสำหรับการออกกำลังกายกราฟหมายเลข 2 รัน:
npm run graph:shuffleGraphTestData 2แบบฝึกหัดกราฟนั้นยอดเยี่ยมสำหรับการทำความเข้าใจความสัมพันธ์การพึ่งพาระหว่างงานอย่างไรก็ตามพวกเขาไม่ครอบคลุมสเปกตรัมเต็มรูปแบบของสถานการณ์ที่เป็นไปได้เนื่องจากมีเพียงงานที่มีการอ้างอิงที่เป็นที่รู้จักในเวลาที่รวบรวมและแก้ไขสามารถแสดงได้ด้วยกราฟ
ดังนั้นเราจึงมีแบบฝึกหัดคอนกรีตหมวดหมู่นี้ซึ่งคุณจะได้รับการนำเสนอด้วยสถานการณ์คอนกรีตที่คุณจะต้องนำไปใช้
เนื่องจากการออกกำลังกายแต่ละครั้งในหมวดหมู่นี้ไม่ซ้ำกันคำอธิบายของพวกเขาจะถูกจัดเรียงด้วยโฟลเดอร์ของพวกเขา
แบบฝึกหัดพื้นฐานได้รับการออกแบบมาเพื่อช่วยเสริมความเข้าใจของคุณเกี่ยวกับรากฐานของสัญญาโดยการปรับปรุงฟังก์ชั่นที่เกี่ยวข้องกับสัญญาและในที่สุดสัญญาเอง
คำอธิบายจะถูกรวมเข้ากับแบบฝึกหัด
การแก้ปัญหาการออกกำลังกายสามารถพบได้ใน repo นี้เช่น https://github.com/henriqueinonhe/promises-training/blob/master/src/exercises/concrete/concurrencyabort/exercise.ts
อย่างไรก็ตามเราขอแนะนำให้คุณตรวจสอบวิธีแก้ปัญหาหลังจากที่คุณแก้ไขการออกกำลังกายด้วยตัวเองเพราะเป้าหมายคือให้คุณเรียนรู้โดยการแก้ปัญหาการออกกำลังกาย
นอกจากนี้โปรดทราบว่าในปัจจุบันการแก้ปัญหาที่นำเสนอนั้น ไม่จำเป็นต้องเป็นสิ่งที่ดีที่สุด ซึ่งหมายความว่าแม้ว่าโซลูชันของคุณจะไม่คล้ายกับสิ่งที่คุณจะพบที่นี่เลย แต่ก็ไม่ได้หมายความว่าพวกเขาไม่ดี
เพื่อความสะดวกในการอัพเกรดเป็นเวอร์ชันใหม่เราได้สร้างสคริปต์การโยกย้ายถิ่นฐานซึ่งจะย้ายการติดตั้งของคุณไปยังเวอร์ชันล่าสุดโดยอัตโนมัติในขณะที่รักษาโซลูชันของคุณ
ในการเรียกใช้สคริปต์การย้ายถิ่นให้เรียกใช้:
npm create promises-training@latest -- --migrateโครงการนี้ได้รับใบอนุญาตภายใต้ CC-BY-NC-ND 4.0
เป้าหมายที่อยู่เบื้องหลังโครงการนี้คือการเป็นทรัพยากรการเรียนรู้ฟรีและเพื่อให้เป็นอิสระและเข้าถึงได้ตลอดไป
นี่คือคำถาม & คำตอบของคำถามทั่วไปเกี่ยวกับใบอนุญาต:
ฉันสามารถใช้โครงการนี้เพื่อการศึกษาด้วยตนเองหรือกลุ่มได้หรือไม่?
ใช่โปรดทำ
ฉันสามารถใช้โครงการนี้ในการฝึกอบรม บริษัท ภายในได้หรือไม่?
ใช่ตราบใดที่คุณให้เครดิตโครงการและทำให้ชัดเจนว่าโครงการนั้น สามารถเข้าถึงได้อย่างอิสระ จากการฝึกอบรม
ฉันสามารถใช้โครงการนี้สำหรับการให้คำปรึกษา/การประชุมเชิงปฏิบัติการที่ชำระเงินได้หรือไม่?
ใช่ตราบใดที่คุณให้เครดิตโครงการทำให้ชัดเจนว่าโครงการนั้น สามารถเข้าถึงได้อย่างอิสระ จากการให้คำปรึกษา/การประชุมเชิงปฏิบัติการทำให้ชัดเจนว่าคุณกำลังเรียกเก็บเงินตามเวลาของคุณและไม่ใช่สำหรับโครงการเองทำให้ชัดเจนว่าโครงการไม่ได้เป็นส่วนหนึ่งของเนื้อหาของคุณเองและทำให้ชัดเจนว่าเราไม่รับรองบริการของคุณ
ฉันสามารถใช้โครงการนี้สำหรับหลักสูตรออนไลน์ที่ชำระเงินได้หรือไม่?
ใช่ตราบใดที่คุณให้เครดิตโครงการทำให้ชัดเจนว่าโครงการสามารถ เข้าถึงได้อย่างอิสระ จากหลักสูตรออนไลน์ทำให้ชัดเจนว่าคุณกำลังเรียกเก็บเงินตามเวลาของคุณและไม่ใช่สำหรับโครงการเองทำให้ชัดเจนว่าโครงการไม่ได้เป็นส่วนหนึ่งของเนื้อหาของคุณเองและทำให้ชัดเจนว่าเราไม่รับรองบริการของคุณ
ฉันสามารถสร้างส้อมของโครงการนี้และใช้เพื่อจุดประสงค์ของฉันเองได้หรือไม่?
ไม่คุณทำไม่ได้ คุณสามารถใช้โครงการนี้ได้โดยไม่มีการแก้ไขใด ๆ นี่เป็นสิ่งจำเป็นเพื่อป้องกันไม่ให้ผู้คนสร้างส้อมแล้วเรียกเก็บเงินสำหรับพวกเขา
ฉันสามารถสร้างหลักสูตรออนไลน์ตามโครงการนี้ได้หรือไม่?
ไม่คุณทำไม่ได้เพราะเราไม่ต้องการให้คนสร้าง "wrappers" รอบโครงการนี้แล้วเรียกเก็บเงินให้พวกเขา
หากคุณมีคำถามใด ๆ เกี่ยวกับใบอนุญาตหรือต้องการพูดคุยเกี่ยวกับกรณีการใช้งานเฉพาะอย่าลังเลที่จะติดต่อฉันที่ [email protected]