คุณอาจเคยได้ยินคำสัญญาและผู้คนจำนวนมากกำลังพูดถึงมันใช้มัน แต่คุณไม่รู้ว่าทำไมพวกเขาถึงพิเศษ คุณไม่สามารถใช้การโทรกลับได้หรือไม่? อะไรพิเศษ? ในบทความนี้ลองมาดูกันว่าสัญญาคืออะไรและวิธีใช้พวกเขาเพื่อเขียนรหัส JavaScript ที่สง่างามมากขึ้น
สัญญาอ่านง่าย
ตัวอย่างเช่นเราต้องการคว้าข้อมูลบางส่วนจาก Hipsterjesus API และเพิ่มข้อมูลนี้ในหน้าของเรา ข้อมูลการตอบสนองของ APIs เหล่านี้มีดังนี้:
{"text": "<p> lorem ipsum ... </p>", "params": {"paras": 4, "type": "hipster-latin"}}ในการใช้การโทรกลับเรามักจะเขียนสิ่งต่อไปนี้:
$ .getJson ('http://hipsterjesus.com/api/', ฟังก์ชั่น (ข้อมูล) {$ ('body') ภาคผนวก (data.text);});หากคุณมีประสบการณ์ในการใช้ jQuery คุณจะรับรู้ว่าเราสร้างคำขอ GET และต้องการการตอบกลับเป็น JSON นอกจากนี้เรายังผ่านฟังก์ชั่นการโทรกลับเพื่อยอมรับ JSON ของการตอบกลับเพื่อเพิ่มข้อมูลลงในเอกสาร
อีกวิธีหนึ่งในการเขียนคือการใช้วัตถุสัญญาที่ส่งคืนโดยวิธี getjson คุณสามารถผูกการโทรกลับไปยังวัตถุที่ส่งคืนนี้ได้โดยตรง
var promition = $ .getJson ('http://hipsterjesus.com/api/'); Promise.done (ฟังก์ชั่น (ข้อมูล) {$ ('body'). ผนวก (data.text);});ในตัวอย่างการโทรกลับข้างต้นจะเพิ่มผลลัพธ์ของคำขอ API ไปยังเอกสารเมื่อการตอบกลับสำเร็จ แต่จะเกิดอะไรขึ้นเมื่อการตอบสนองล้มเหลว? เราสามารถผูกโปรเซสเซอร์ที่ล้มเหลวตามสัญญาของเรา
var promise = $ .getJson ('http://hipsterjesus.com/api/'); Promise.done (ฟังก์ชั่น (ข้อมูล) {$ ('body'). ผนวก (data.text);}); promise.fail (ฟังก์ชั่น () {$ ('body')คนส่วนใหญ่ลบตัวแปรสัญญาซึ่งกระชับมากขึ้นและสามารถดูฟังก์ชั่นของรหัสได้อย่างรวดเร็ว
$ .getJson ('http://hipsterjesus.com/api/') .done (ฟังก์ชั่น (ข้อมูล) {$ ('ร่างกาย'). ต่อไป (data.text);}). ล้มเหลว (ฟังก์ชั่น () {$ (ร่างกาย ') ผนวก (' <p> ไม่ผิด! </p> ');};JQuery ยังมีตัวจัดการเหตุการณ์ที่เกิดขึ้นตลอดเวลาและจะถูกเรียกโดยไม่คำนึงถึงความสำเร็จหรือความล้มเหลว
$ .getJson ('http://hipsterjesus.com/api/') .done (ฟังก์ชั่น (ข้อมูล) {$ ('ร่างกาย') ผนวก (data.text);}). ล้มเหลว (ฟังก์ชั่น () {$ (ร่างกาย ') จะเพิ่มเสมอ!. </p> ');โดยการใช้สัญญาลำดับการโทรกลับเป็นไปตามที่คาดไว้ เราสามารถตรวจสอบให้แน่ใจว่าการโทรกลับปกติเรียกว่าก่อนจากนั้นการโทรกลับที่ล้มเหลวและในที่สุดการโทรกลับที่เกิดขึ้น
API ที่ดีกว่า
ตัวอย่างเช่นเราต้องการสร้างวัตถุที่ห่อหุ้มของ Hipsterjesus API เราจะเพิ่มวิธีการ - HTML ซึ่งส่งคืนข้อมูล HTML จาก API ซึ่งแตกต่างจากการตั้งค่าโปรเซสเซอร์การโทรกลับเพื่อแยกการร้องขอเราสามารถให้วิธีการส่งคืนวัตถุสัญญา
var hipsterjesus = {html: function () {return $ .getJson ('http://hipsterjesus.com/api/') -สิ่งนี้เจ๋งมากดังนั้นเราจึงสามารถข้ามวัตถุสัญญาได้โดยไม่ต้องกังวลว่าจะแยกวิเคราะห์ค่าของมันเมื่อใดหรืออย่างไร รหัสใด ๆ ที่ต้องใช้ค่าคืนสัญญาสามารถลงทะเบียนได้ด้วยการโทรกลับการตอบกลับที่ประสบความสำเร็จ
วิธีนี้ช่วยให้เราสามารถปรับเปลี่ยนผลลัพธ์ของสัญญาและส่งผ่านไปยังโปรเซสเซอร์ถัดไปในห่วงโซ่ ซึ่งหมายความว่าตอนนี้เราสามารถใช้ API ใหม่เช่นนี้:
hipsterjesus.html (). ทำ (ฟังก์ชั่น (html) {$ ("ร่างกาย"). ผนวก (html);});จนกระทั่งเมื่อไม่นานมานี้ AngularJS มีคุณสมบัตินักฆ่าซึ่งเทมเพลตสามารถผูกพันกับสัญญาโดยตรง ในคอนโทรลเลอร์ของ Angular เช่นนี้:
$ scope.hipsteripsum = $ http.get ('http://hipsterjesus.com/api/');ด้วยวิธีนี้มันง่ายมากที่จะเขียน {{hipsteripsum.text}} ในเทมเพลต เมื่อสัญญาแก้ไข Angular ไม่จำเป็นต้องอัปเดตมุมมองโดยอัตโนมัติ น่าเสียดายที่ทีม Angular ได้ละทิ้งคุณสมบัตินี้ ตอนนี้สามารถเปิดใช้งานได้โดยเรียก $ parseprovider.unwrappromises (จริง) ฉันหวังว่า Angular จะมีคุณสมบัตินี้อยู่แล้วในเฟรมเวิร์กอื่น ๆ (ฉันจะจับตาดูมัน)
สายโซ่
ส่วนที่ดีที่สุดเกี่ยวกับคำสัญญาคือคุณสามารถผูกเข้าด้วยกันได้ ตัวอย่างเช่นเราต้องการเพิ่มวิธีการใน API ที่ส่งคืนอาร์เรย์
var hipsterjesus = {html: function () {return $ .getJson ('http://hipsterjesus.com/api/') }, ย่อหน้า: function () {return this.html (). จากนั้น (ฟังก์ชั่น (html) {return html.replace (/<[^>]+>/g, "") .split ("");}); -เราใช้วิธี HTML นี้ในวิธีการข้างต้นเราใช้มันในวิธีย่อหน้า เนื่องจากค่าการส่งคืนของฟังก์ชั่นการเรียกกลับสัญญาถูกส่งผ่านไปยังการโทรกลับครั้งต่อไปในห่วงโซ่เรามีอิสระที่จะสร้างวิธีการที่ใช้งานได้ขนาดเล็กเพื่อเปลี่ยนข้อมูลเมื่อผ่านผ่าน
เราสามารถเชื่อมต่อสัญญาได้ตลอดเวลาตามต้องการ มาเพิ่มกันเถอะ
var hipsterjesus = {html: function () {return $ .getJson ('http://hipsterjesus.com/api/') }, ย่อหน้า: function () {return this.html (). จากนั้น (ฟังก์ชั่น (html) {return html.replace (/<[^>]+>/g, "") .split ("");}); }, ประโยค: function () {return this.paragraphs (). จากนั้น (ฟังก์ชั่น (ย่อหน้า) {return [] .concat.apply ([], paragraphs.map (ฟังก์ชัน (ย่อหน้า) {return paragraph.split ( /. /. /);});}); -หลายสาย
บางทีคุณสมบัติที่โดดเด่นที่สุดของสัญญาคือความสามารถในการเรียก API หลายรายการ จะเกิดอะไรขึ้นถ้าคุณต้องการสร้างการโทร API สองสายในเวลาเดียวกันเมื่อใช้การโทรกลับ คุณอาจเขียนสิ่งนี้:
var firstData = null; var secondData = null; var responsecallback = function () {if (! firstData ||! secondData) return; // ทำอะไรบางอย่าง} $. รับ ("http://example.com/first", ฟังก์ชั่น (ข้อมูล) {firstData = data; Responsecallback ();}); $ .get ("http://example.com/second", ฟังก์ชั่น (ข้อมูล) {secondData = data; responsecallback ();});นี่เป็นสัญญาที่ใช้งานง่ายกว่ามาก:
var firstPromise = $ .get ("http://example.com/first"); var secondPromise = $ .get ("http://example.com/second"); $. เมื่อ (FirstPromise, SecondPromise) .done (ฟังก์ชั่น (FirstData, SecondData) {// ทำอะไร});ที่นี่เราใช้วิธีการเมื่อเชื่อมโยงกับโปรเซสเซอร์ที่เรียกว่าเมื่อคำขอทั้งสองเสร็จสิ้น
สรุปแล้ว
นี่คือสัญญา ฉันหวังว่าคุณจะนึกถึงสิ่งที่น่ากลัวในทันทีที่สามารถบรรลุได้ด้วยคำสัญญา คุณชอบอะไรมากที่สุดเกี่ยวกับการใช้มัน? บอกฉันในความคิดเห็น!
*หมายเหตุ: เพื่อความเรียบง่ายบทความนี้ใช้การดำเนินการล่าช้าของ jQuery มีความแตกต่างเล็กน้อยระหว่างวัตถุ jQuery รอการตัดบัญชีและข้อกำหนดของสัญญา/A+ ซึ่งเป็นมาตรฐานมากขึ้น
บทความข้างต้นวิธีการใช้สัญญาที่จะเขียนรหัส JavaScript ที่สง่างามมากขึ้นคือเนื้อหาทั้งหมดที่ฉันแบ่งปันกับคุณ ฉันหวังว่ามันจะให้ข้อมูลอ้างอิงและฉันหวังว่าคุณจะสนับสนุน wulin.com มากขึ้น