วิธีการปฏิเสธคำสัญญาจากภายในแล้วฟังก์ชั่น


86

นี่อาจเป็นคำถามโง่ ๆ แต่คำสัญญากลางคุณจะปฏิเสธคำสัญญาจากภายในหนึ่งในฟังก์ชั่นนี้ได้อย่างไร ตัวอย่างเช่น:

someActionThatReturnsAPromise()
    .then(function(resource) {
        return modifyResource(resource)
    })
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource)) {
            var validationError = getValidationError(modifiedResource);
            // fail promise with validationError
        }
    })
    .catch(function() {
        // oh noes
    });

ไม่มีการอ้างอิงถึงฟังก์ชันแก้ไข / ปฏิเสธดั้งเดิมหรือ PromiseResolver อีกต่อไป ฉันควรจะเพิ่มreturn Promise.reject(validationError);ไหม


1
throw validationError
kavun

> <ฉันรู้สึกว่ามันจะเป็นอะไรที่งี่เง่า / ง่ายขนาดนั้น เดาว่าฉันคิดอยู่เสมอว่าฉันต้องเรียกใช้ฟังก์ชันปฏิเสธโดยเฉพาะหรือส่งคืนสัญญาที่ล้มเหลวแทน ดังนั้นจากภายในคำสัญญา / จากนั้นได้ค่าที่ส่งคืนใด ๆ ที่ไม่ใช่สัญญาใหม่จะถือว่าเป็นค่าที่แก้ไขแล้ว? และถ้าฉันทำผิดพลาดนั่นจะเหมือนกับการส่งคืนสัญญาที่ถูกปฏิเสธทันทีใช่หรือไม่? ถ้าคุณโพสต์เป็นคำตอบฉันจะยอมรับมัน
chinabuffet

คุณคงกำลังมองหาคำตอบที่ยอมรับได้ที่นี่stackoverflow.com/questions/17800176/…
crad

คำตอบ:


96

ฉันควรจะเพิ่มreturn Promise.reject(validationError);ไหม

ใช่. อย่างไรก็ตามมันซับซ้อนเฉพาะใน jQuery ด้วยไลบรารีPromise / A + -compliant ที่คุณสามารถทำได้

throw validationError;

ดังนั้นรหัสของคุณจะมีลักษณะดังนี้

someActionThatReturnsAPromise()
    .then(modifyResource)
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource))
            throw getValidationError(modifiedResource);
        // else !
        return modifiedResource;
    })
    .catch(function() {
        // oh noes
    });

3
นี่เป็นสิ่งที่ต้องทำปกติหรือไม่? มีการใช้กันอย่างแพร่หลายหรือไม่? ฉันรู้สึกแย่ที่ทำแบบนี้เพราะถ้ามีบางส่วนในรหัส.catchหายไปแอปทั้งหมดจะระเบิดขึ้นพร้อมกับข้อผิดพลาดที่ไม่ได้รับการแก้ไข ..
Andrey Popov

3
โปรดทราบว่าในไลบรารีที่สอดคล้องกับ Promise / A + คุณสามารถใช้ throw ได้เนื่องจากhandlerfor thenคือการซิงค์และสามารถจับข้อยกเว้นได้ หากตัวจัดการไม่ซิงค์จะต้องส่งคืนสัญญาที่จะปฏิเสธในที่สุด ดังนั้นการคืน Promise.reject () เสมอแทนที่จะขว้างก็สมเหตุสมผลสำหรับฉัน เพราะถ้าคุณใส่ตัวจัดการ async ห้องสมุดจะไม่สามารถจับมันได้และมันจะผ่านไปอย่างเงียบ ๆ ระวัง.
Mike Gleason jr Couturier

1
@MikeGleasonjrCouturier: ไม่ควรมีตัวจัดการ async ที่ไม่ใช่.thenตัวจัดการตามสัญญา :-) หากคุณใช้ API ที่ไม่ได้รับการรับรองก็return Promise.reject()จะช่วยคุณได้
Bergi

@Bergi ฉันหมายถึง: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); แก้ไข: โอเคฉันอ่านความคิดเห็นของคุณอีกครั้งฉันอยู่กับคุณทั้งหมดเราอยู่ในหน้าเดียวกัน! ฉันต้องการชี้ให้เห็นถึง OP :)
Mike Gleason jr Couturier

1
@MikeGleasonjrCouturier: ใช่นั่นคือสิ่งที่ฉันพูด และdoAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })ใช้งานไม่ได้เช่นกัน - มันล้มเหลวอย่างเงียบ ๆ ควรจะเป็นdoAsync().then(function() { throw new Error("will be caught"); })เมื่อคุณทำงานด้วยคำสัญญา
Bergi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.