Muitas das respostas aqui são semelhantes ao último exemplo deste artigo . Estou armazenando em cache várias promessas e as funções resolve()
e reject()
podem ser atribuídas a qualquer variável ou propriedade. Como resultado, sou capaz de tornar esse código um pouco mais compacto:
function defer(obj) {
obj.promise = new Promise((resolve, reject) => {
obj.resolve = resolve;
obj.reject = reject;
});
}
Aqui está um exemplo simplificado de uso desta versão de defer()
para combinar uma FontFace
carga Promise com outro processo assíncrono:
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
Atualização: 2 alternativas, caso você queira encapsular o objeto:
function defer(obj = {}) {
obj.promise = new Promise((resolve, reject) => {
obj.resolve = resolve;
obj.reject = reject;
});
return obj;
}
let deferred = defer();
e
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
}
let deferred = new Deferred();
Promise
deve ser executado de forma síncrona para permitir "exportar" as duas funções.