Aplikujemy podejście error-first w czystym JavaScript zamiast wzorca z Promise. Do dzieła.

Przypomnijmy sobie ten przykład:

function whenLoaded(){
    let p = new Promise(function(resolve, reject){

    let stateCheck = setInterval(() => {
        if (document.readyState === 'complete') {
              clearInterval(stateCheck);
              resolve(true);
            }
        }, 100);

    });
    return p;
}

function selectById(selector){
    let p = new Promise(function(resolve, reject){

        let element;
        
        try {
            element = document.getElementById(selector);
            resolve(element);
        } catch(err) {
            reject(err.message);
        }

    });

    return p;
}

whenLoaded()
.then(function(){
    console.log("DOCUMENT READY");

    selectById("para")
    .then((el) => el.textContent = 'modified')

    selectById("doesntexist")
    .then((el) => el.textContent = "modified!")
    .catch((err) => console.warn(err));
});

console.log(document.readyState);
//loading
//DOCUMENT READY

Odtwarzamy selectById bez promise, z podejściem error-first:

function selectById(selector, cb){
    let element = document.getElementById(selector);
    if(element === null){
        return cb(true, null);
    } else {
        return cb(false, element);
    }
}

Tutaj dałem true i false, ale zazwyczaj error first polega na przekazaniu tylko errora gdy błąd oraz nulla i argumentów, jeżeli ok. Aczkolwiek w ten sposób też to jest stosowane, np. fs.exists z node.js z modułu filesystem.

Teraz zobaczmy, jak to działa:

window.addEventListener('DOMContentLoaded', function(){
    selectById("para", function(err, p){

        if(err){
            console.warn('element doestn exist');
            return;
        }

        p.textContent = "MODIFIED";
    });
    selectById("nonexisting", function(err, el){

        if(err){
            console.warn('element doestn exist');
            return;
        }
        
        el.textContent = "MODIFIED";

    });
});

Łatwiejsze, niż się wydaje.