การส่งผ่านอย่างชัดเจน
เช่นเดียวกับการซ้อนหมายเลขโทรกลับเทคนิคนี้อาศัยการปิด กระนั้นโซ่นั้นยังคงแบน - แทนที่จะส่งผ่านเฉพาะผลลัพธ์ล่าสุดวัตถุบางสถานะจะถูกส่งผ่านไปทุกขั้นตอน วัตถุสถานะเหล่านี้จะรวบรวมผลลัพธ์ของการกระทำก่อนหน้านี้โดยแจกค่าทั้งหมดที่จำเป็นในภายหลังอีกครั้งพร้อมกับผลลัพธ์ของงานปัจจุบัน
function getExample() {
    return promiseA(…).then(function(resultA) {
        // some processing
        return promiseB(…).then(b => [resultA, b]); // function(b) { return [resultA, b] }
    }).then(function([resultA, resultB]) {
        // more processing
        return // something using both resultA and resultB
    });
}
ที่นี่ลูกศรเล็ก ๆb => [resultA, b]นั้นเป็นฟังก์ชั่นที่ปิดresultAและส่งผ่านอาร์เรย์ของผลลัพธ์ทั้งสองไปยังขั้นตอนถัดไป ซึ่งใช้ไวยากรณ์การทำลายโครงสร้างพารามิเตอร์เพื่อแยกค่าในตัวแปรเดี่ยวอีกครั้ง
ก่อนที่จะมีการทำลายโครงสร้างพร้อมใช้งานกับ ES6 วิธีการช่วยเหลือที่ดีที่.spread()ถูกเรียกใช้นั้นจัดทำโดยห้องสมุดสัญญาหลายแห่ง ( Q , Bluebird , เมื่อ , ... ) มันต้องใช้ฟังก์ชั่นที่มีหลายพารามิเตอร์ - หนึ่งสำหรับแต่ละองค์ประกอบอาร์เรย์ - .spread(function(resultA, resultB) { …เพื่อนำมาใช้เป็น
แน่นอนว่าการปิดที่จำเป็นในที่นี้สามารถทำให้ง่ายขึ้นโดยฟังก์ชันผู้ช่วยบางอย่างเช่น
function addTo(x) {
    // imagine complex `arguments` fiddling or anything that helps usability
    // but you get the idea with this simple one:
    return res => [x, res];
}
…
return promiseB(…).then(addTo(resultA));
หรือคุณสามารถใช้Promise.allเพื่อสร้างคำสัญญาสำหรับอาร์เรย์:
function getExample() {
    return promiseA(…).then(function(resultA) {
        // some processing
        return Promise.all([resultA, promiseB(…)]); // resultA will implicitly be wrapped
                                                    // as if passed to Promise.resolve()
    }).then(function([resultA, resultB]) {
        // more processing
        return // something using both resultA and resultB
    });
}
และคุณอาจไม่เพียง แต่ใช้อาร์เรย์ แต่วัตถุที่ซับซ้อนโดยพลการ ตัวอย่างเช่นด้วย_.extendหรือObject.assignในฟังก์ชั่นตัวช่วยที่แตกต่างกัน:
function augment(obj, name) {
    return function (res) { var r = Object.assign({}, obj); r[name] = res; return r; };
}
function getExample() {
    return promiseA(…).then(function(resultA) {
        // some processing
        return promiseB(…).then(augment({resultA}, "resultB"));
    }).then(function(obj) {
        // more processing
        return // something using both obj.resultA and obj.resultB
    });
}
ในขณะที่รูปแบบนี้รับประกันโซ่แบนและวัตถุสถานะชัดเจนสามารถปรับปรุงความคมชัดมันจะกลายเป็นน่าเบื่อสำหรับสายยาว โดยเฉพาะอย่างยิ่งเมื่อคุณต้องการสถานะเป็นระยะ ๆ คุณยังต้องผ่านทุกขั้นตอน ด้วยอินเทอร์เฟซแบบคงที่นี้การโทรกลับครั้งเดียวในเครือจะค่อนข้างแน่นหนาและยืดหยุ่นไม่เปลี่ยนแปลง มันทำให้การแยกตัวออกจากขั้นตอนเดียวยากขึ้นและการโทรกลับไม่สามารถจัดหาได้โดยตรงจากโมดูลอื่น ๆ - พวกเขาจำเป็นต้องห่อด้วยรหัสสำเร็จรูปที่ใส่ใจเกี่ยวกับสถานะ ฟังก์ชั่นผู้ช่วยที่เป็นนามธรรมเช่นด้านบนสามารถลดความเจ็บปวดได้เล็กน้อย แต่จะมีอยู่เสมอ
               
              
javascriptแต่ก็มีความเกี่ยวข้องในภาษาอื่น ฉันใช้คำตอบ "break the chain"ใน java และjdeferred