จะจัดการกับ if-else ในสัญญาได้อย่างไร?


87

ในบางกรณีเมื่อฉันได้รับค่าส่งคืนจากวัตถุสัญญาฉันต้องเริ่มต้นพรีเซสสองรายการที่แตกต่างกันthen()ขึ้นอยู่กับเงื่อนไขของค่าเช่น:

promise().then(function(value){
    if(//true) {
        // do something
    } else {
        // do something 
    }
})

ฉันคิดว่าอาจจะเขียนได้ว่า:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        ifTruePromise().then();
    } else {
        ifFalsePromise().then();
    }
})

แต่ด้วยสิ่งนี้ฉันมีสองคำถาม:

  1. ฉันไม่แน่ใจว่าเป็นความคิดที่ดีหรือไม่ที่จะเริ่มต้นสัญญาใหม่จากนั้นดำเนินการตามคำสัญญา

  2. จะเกิดอะไรขึ้นถ้าฉันต้องการให้สองกระบวนการเรียกใช้ฟังก์ชันหนึ่งในครั้งสุดท้าย? หมายความว่ามี "ขั้ว" เดียวกัน

ฉันพยายามที่จะคืนสัญญาใหม่เพื่อรักษาห่วงโซ่เดิมเช่น:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        // and return it
        return ifTruePromise();
    } else {
        // do something, no new promise
        // hope to stop the then chain
    }
}).then(// I can handle the result of ifTruePromise here now);

แต่ในกรณีนี้ไม่ว่าจะเป็นจริงหรือเท็จสิ่งต่อไปthenจะใช้ได้

แล้วแนวทางปฏิบัติที่ดีที่สุดในการจัดการคืออะไร?


1
อาจเป็นสิ่งที่คุณกำลังมองหาstackoverflow.com/questions/26599798/… ?
vinayr

คำตอบ:


61

ตราบใดที่ฟังก์ชันของคุณคืนสัญญาคุณสามารถใช้วิธีแรกที่คุณแนะนำได้

ซอด้านล่างแสดงให้เห็นว่าคุณสามารถใช้เส้นทางโซ่ต่างๆได้อย่างไรโดยขึ้นอยู่กับค่าที่แก้ไขครั้งแรก

function myPromiseFunction() {
	//Change the resolved value to take a different path
    return Promise.resolve(true);
}

function conditionalChaining(value) {
    if (value) {
        //do something
        return doSomething().then(doSomethingMore).then(doEvenSomethingMore);
    } else {
        //do something else
        return doSomeOtherThing().then(doSomethingMore).then(doEvenSomethingMore);
    }
}

function doSomething() {
    console.log("Inside doSomething function");
    return Promise.resolve("This message comes from doSomeThing function");
}

function doSomeOtherThing() {
    console.log("Inside doSomeOtherthing function");
    return Promise.resolve("This message comes from doSomeOtherThing function");
}

function doSomethingMore(message) {
    console.log(message);
    return Promise.resolve("Leaving doSomethingMore");
}

function doEvenSomethingMore(message) {
    console.log("Inside doEvenSomethingMore function");
    return Promise.resolve();
}

myPromiseFunction().then(conditionalChaining).then(function () {
    console.log("All done!");
}).
catch (function (e) {

});

นอกจากนี้คุณยังสามารถสร้างการผูกมัดแบบมีเงื่อนไขกำหนดสัญญาการส่งคืนให้กับตัวแปรจากนั้นให้เรียกใช้ฟังก์ชันที่ควรจะรันด้วยวิธีใดก็ได้

function conditionalChaining(value){
    if (value) {
        //do something
        return doSomething();
    } else{
        //do something else
        return doSomeOtherThing();
    }
}

var promise = myPromiseFunction().then(conditionalChaining);

promise.then(function(value){
    //keep executing functions that should be called either way
});

4

ฉันได้เขียนแพ็คเกจง่ายๆสำหรับการใช้สัญญาแบบมีเงื่อนไข

หากคุณต้องการตรวจสอบ:

หน้า npm: https://www.npmjs.com/package/promise-tree

และ github: https://github.com/shizongli94/promise-tree

ในการตอบกลับความคิดเห็นที่ถามว่าแพ็คเกจแก้ปัญหาอย่างไร:

1 มีสองวัตถุ

2, Branch object ในแพ็กเกจนี้เป็นที่เก็บชั่วคราวสำหรับฟังก์ชันต่างๆเช่น onFulfilled และ onRejected ที่คุณต้องการใช้ใน then () หรือ catch () มีวิธีการเช่น then () และ catch () ซึ่งใช้อาร์กิวเมนต์เดียวกันกับคู่สัญญาใน Promise เมื่อคุณส่งการติดต่อกลับใน Branch.then () หรือ Branch.catch () ให้ใช้ไวยากรณ์เดียวกันกับ Promise.then () และ Promise.catch () จากนั้นไม่ต้องทำอะไรเลยนอกจากการจัดเก็บการเรียกกลับในอาร์เรย์

3 เงื่อนไขเป็นออบเจ็กต์ JSON ที่เก็บเงื่อนไขและข้อมูลอื่น ๆ สำหรับการตรวจสอบและการแยกสาขา

4 คุณระบุเงื่อนไข (นิพจน์บูลีน) โดยใช้อ็อบเจกต์เงื่อนไขในการเรียกกลับสัญญา จากนั้น Condition จะจัดเก็บข้อมูลที่คุณส่งผ่านหลังจากที่ผู้ใช้ให้ข้อมูลที่จำเป็นทั้งหมดแล้ววัตถุเงื่อนไขจะใช้วิธีการสร้างวัตถุ Promise ใหม่ทั้งหมด ส่วนที่ยุ่งยากเล็กน้อยที่นี่คือคุณ (ในฐานะผู้ใช้งานไม่ใช่ผู้ใช้) ต้องแก้ไข / ปฏิเสธสัญญาที่คุณสร้างขึ้นด้วยตนเองก่อนที่จะผูกมัดการเรียกกลับที่จัดเก็บไว้ เนื่องจากไม่เช่นนั้นห่วงโซ่สัญญาใหม่จะไม่เริ่มต้น

5 ขอบคุณเหตุการณ์วนรอบวัตถุสาขาสามารถสร้างอินสแตนซ์ได้ทั้งก่อนหรือหลังคุณมีวัตถุ Stem Promise และพวกมันจะไม่รบกวนซึ่งกันและกัน ฉันใช้คำว่า "กิ่ง" และ "ลำต้น" ในที่นี้เพราะโครงสร้างคล้ายต้นไม้

โค้ดตัวอย่างสามารถพบได้ทั้งในหน้า npm และ github

อย่างไรก็ตามการใช้งานนี้ยังช่วยให้คุณมีสาขาภายในสาขา และสาขาไม่จำเป็นต้องอยู่ที่เดียวกันกับที่คุณตรวจสอบเงื่อนไข


ดูเหมือนว่าคุณกำลังแสดงความคิดเห็นแทนคำตอบ เมื่อคุณมีชื่อเสียงเพียงพอแล้วคุณจะสามารถแสดงความคิดเห็นในโพสต์ใดก็ได้ ตรวจสอบสิ่งนี้ด้วยว่าฉันทำอะไรได้บ้าง
thewaywewere

@thewaywewere ฉันได้เพิ่มรายละเอียดการใช้งานที่ตอบสนองคำขอของคุณแล้ว
szl1919

0

นี่คือวิธีที่ฉันทำในการดึงข้อมูล () ฉันไม่แน่ใจว่านี่เป็นวิธีที่ถูกต้องหรือไม่ แต่ได้ผล

 fetch().then(res => res.ok ? res : false).then(res => {
    if (res) {
        //res ok
    } else {
       //res not ok
    }

});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.