นี่คือวิธีที่ฉันคิดว่าคุณควรทำ
แยกโซ่
เนื่องจากทั้งสองฟังก์ชั่นจะใช้amazingDataจึงเหมาะสมที่จะมีไว้ในฟังก์ชันเฉพาะ ฉันมักจะทำแบบนั้นทุกครั้งที่ต้องการนำข้อมูลบางส่วนกลับมาใช้ใหม่ดังนั้นจึงแสดงเป็นฟังก์ชัน arg เสมอ
เนื่องจากตัวอย่างของคุณกำลังเรียกใช้โค้ดบางส่วนฉันจะสมมติว่ามีการประกาศทั้งหมดในฟังก์ชัน ผมจะเรียกมันว่าtoto () จากนั้นเราก็จะมีฟังก์ชั่นอื่นซึ่งจะใช้ทั้งafterSomething ()และafterSomethingElse ()
function toto() {
return somethingAsync()
.then( tata );
}
นอกจากนี้คุณจะสังเกตเห็นว่าฉันได้เพิ่มคำสั่งส่งคืนเนื่องจากโดยปกติแล้วเป็นวิธีที่จะไปกับคำสัญญา - คุณจะคืนคำสัญญาเสมอเพื่อให้เราสามารถผูกมัดต่อไปได้หากจำเป็น ที่นี่somethingAsync ()จะสร้างamazingDataและจะพร้อมใช้งานทุกที่ภายในฟังก์ชันใหม่
ตอนนี้ฟังก์ชั่นใหม่นี้จะมีลักษณะอย่างไรโดยทั่วไปขึ้นอยู่กับprocessAsync () asynchronous ด้วยหรือไม่?
processAsync ไม่ใช่อะซิงโครนัส
ไม่มีเหตุผลที่จะทำให้สิ่งต่าง ๆ ซับซ้อนมากเกินไปถ้าprocessAsync ()ไม่ใช่แบบอะซิงโครนัส รหัสลำดับที่ดีเก่า ๆ บางตัวจะทำให้ได้
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
โปรดทราบว่าไม่สำคัญว่าafterSomethingElse ()กำลังทำสิ่งที่ไม่ตรงกันหรือไม่ หากเป็นเช่นนั้นคำสัญญาจะกลับคืนมาและโซ่จะดำเนินต่อไปได้ หากไม่เป็นเช่นนั้นค่าผลลัพธ์จะถูกส่งกลับ แต่เนื่องจากฟังก์ชันถูกเรียกใช้จากนั้น ()ค่าจะถูกรวมไว้ในคำสัญญาต่อไป (อย่างน้อยก็ใน Javascript แบบดิบ)
processAsync แบบอะซิงโครนัส
หากprocessAsync ()เป็นแบบอะซิงโครนัสโค้ดจะมีลักษณะแตกต่างกันเล็กน้อย ที่นี่เราจะพิจารณาว่าafterSomething ()และafterSomethingElse ()จะไม่ถูกนำกลับมาใช้ที่อื่น
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
เช่นเดียวกับก่อนสำหรับafterSomethingElse () สามารถเป็นแบบอะซิงโครนัสหรือไม่ก็ได้ คำสัญญาจะถูกส่งกลับหรือมูลค่าที่รวมอยู่ในคำสัญญาที่ได้รับการแก้ไขแล้ว
รูปแบบการเขียนโค้ดของคุณค่อนข้างใกล้เคียงกับที่ฉันใช้นั่นคือเหตุผลที่ฉันตอบแม้จะผ่านไป 2 ปี ฉันไม่ใช่แฟนตัวยงของการมีฟังก์ชั่นที่ไม่ระบุตัวตนทุกที่ หาอ่านยากจัง แม้ว่าจะพบได้ค่อนข้างบ่อยในชุมชนก็ตาม. มันเป็นเรื่องที่เราถูกแทนที่ด้วยการเรียกกลับนรกโดยสัญญา-นรก
ฉันยังต้องการที่จะทำให้ชื่อของฟังก์ชั่นในนั้นสั้น พวกเขาจะถูกกำหนดไว้ในเครื่องเท่านั้น และส่วนใหญ่แล้วพวกเขาจะเรียกใช้ฟังก์ชันอื่นที่กำหนดไว้ที่อื่นซึ่งสามารถใช้ซ้ำได้เพื่อทำงาน ฉันทำเช่นนั้นสำหรับฟังก์ชันที่มีเพียง 1 พารามิเตอร์ดังนั้นฉันไม่จำเป็นต้องรับฟังก์ชันเข้าและออกเมื่อฉันเพิ่ม / ลบพารามิเตอร์ลงในลายเซ็นฟังก์ชัน
ตัวอย่างการรับประทานอาหาร
นี่คือตัวอย่าง:
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
อย่าให้ความสำคัญกับPromise.resolve ()มากเกินไป เป็นเพียงวิธีที่รวดเร็วในการสร้างคำสัญญาที่ได้รับการแก้ไข สิ่งที่ฉันพยายามที่จะบรรลุตามนี้คือการมีทุกรหัสฉันทำงานในสถานที่เดียว - เพียงแค่ใต้thens ฟังก์ชันอื่น ๆ ทั้งหมดที่มีชื่อที่สื่อความหมายสามารถนำมาใช้ซ้ำได้
ข้อเสียเปรียบของเทคนิคนี้คือการกำหนดฟังก์ชันจำนวนมาก แต่มันเป็นความเจ็บปวดที่จำเป็นฉันกลัวเพื่อหลีกเลี่ยงการมีฟังก์ชั่นที่ไม่ระบุตัวตนทั่วทุกที่ และอะไรคือความเสี่ยงต่อไป: stack overflow? (เรื่องตลก!)
การใช้อาร์เรย์หรือวัตถุตามที่กำหนดไว้ในคำตอบอื่น ๆ ก็ใช้ได้เช่นกัน หนึ่งในวิธีที่นี้เป็นคำตอบที่เสนอโดยเควินเรด
นอกจากนี้คุณยังสามารถใช้ผูก ()หรือPromise.all () โปรดทราบว่าพวกเขายังต้องการให้คุณแยกรหัสของคุณ
ใช้ผูก
หากคุณต้องการที่จะให้การทำงานของคุณนำมาใช้ใหม่ แต่ไม่ได้จริงๆต้องให้สิ่งที่อยู่ภายในนั้นสั้นมากคุณสามารถใช้ผูก ()
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
เพื่อให้ง่ายการผูก ()จะนำหน้ารายการ args (ยกเว้นอันแรก) ไปยังฟังก์ชันเมื่อมีการเรียกใช้
โดยใช้ Promise.all
ในโพสต์ของคุณคุณ mentionned การใช้งานของการแพร่กระจาย () ฉันไม่เคยใช้กรอบงานที่คุณใช้ แต่นี่คือวิธีที่คุณควรใช้
บางคนเชื่อว่าPromise.all ()เป็นวิธีแก้ปัญหาทั้งหมดดังนั้นฉันจึงสมควรกล่าวถึง
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
คุณสามารถส่งผ่านข้อมูลไปยังPromise.all () - สังเกตการมีอยู่ของอาร์เรย์ - ตราบใดที่สัญญา แต่ตรวจสอบให้แน่ใจว่าไม่มีคำสัญญาใดล้มเหลวมิฉะนั้นจะหยุดประมวลผล
และแทนที่จะกำหนดตัวแปรใหม่จากอาร์กิวเมนต์ argsคุณควรจะสามารถใช้spread ()แทนthen ()สำหรับงานที่ยอดเยี่ยมทุกประเภท