หลายคำตอบที่นี่จะคล้ายกับตัวอย่างสุดท้ายในบทความนี้ ฉันแคชสัญญาหลายรายการresolve()
และreject()
สามารถกำหนดฟังก์ชันและให้กับตัวแปรหรือคุณสมบัติใด ๆ ดังนั้นฉันสามารถทำให้รหัสนี้มีขนาดเล็กลงเล็กน้อย:
function defer(obj) {
obj.promise = new Promise((resolve, reject) => {
obj.resolve = resolve;
obj.reject = reject;
});
}
นี่คือตัวอย่างที่ง่ายของการใช้เวอร์ชันนี้defer()
เพื่อรวมการFontFace
โหลด Promise กับกระบวนการ async อื่น:
function onDOMContentLoaded(evt) {
let all = []; // array of Promises
glob = {}; // global object used elsewhere
defer(glob);
all.push(glob.promise);
// launch async process with callback = resolveGlob()
const myFont = new FontFace("myFont", "url(myFont.woff2)");
document.fonts.add(myFont);
myFont.load();
all.push[myFont];
Promise.all(all).then(() => { runIt(); }, (v) => { alert(v); });
}
//...
function resolveGlob() {
glob.resolve();
}
function runIt() {} // runs after all promises resolved
อัปเดต: 2 ทางเลือกในกรณีที่คุณต้องการห่อหุ้มวัตถุ:
function defer(obj = {}) {
obj.promise = new Promise((resolve, reject) => {
obj.resolve = resolve;
obj.reject = reject;
});
return obj;
}
let deferred = defer();
และ
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
}
let deferred = new Deferred();
Promise
จะต้องดำเนินการพร้อมกันเพื่อให้ "ส่งออก" ทั้งสองฟังก์ชั่น