em JavaScript, como cumprir uma promessa em tempo limite?

É um padrão comum implementar tempo limite de alguma função assíncrona, usando deffered / promessa:

// Create a Deferred and return its Promise
function timeout(funct, args, time) {
    var dfd = new jQuery.Deferred();

    // execute asynchronous code
    funct.apply(null, args);

    // When the asynchronous code is completed, resolve the Deferred:
    dfd.resolve('success');

    setTimeout(function() {
        dfd.reject('sorry');
    }, time);
    return dfd.promise();
}

Agora podemos executar alguma função assíncrona chamadamyFunc e lidar com o tempo limite:

// Attach a done and fail handler for the asyncEvent
$.when( timeout(myFunc, [some_args], 1000) ).then(
    function(status) {
        alert( status + ', things are going well' );
    },
    function(status) {
        alert( status + ', you fail this time' );
    }
);

OK, vamos dar uma reviravolta nesta história! Imagine que omyFunc próprio retorna uma promessa (NOTA: promessa NÃO adiada e não posso alterá-la):

function myFunc(){
    var dfd = new jQuery.Deffered();
    superImportantLibrary.doSomething(function(data)){
       if(data.length < 5){
            dfd.reject('too few data');
       }
       else{
           dfd.resolve('success!');
       }
    }, {'error_callback': function(){
        dfd.reject("there was something wrong but it wasn't timeout");}
    }});
    return dfd.promise();
}

Agora, se eu enrolarmyFunc notimeout, Perderei a capacidade de lidar com erros diferentes do tempo limite. E semyFunc emitir eventos de progresso, vou perder isso também.

Então a questão é: como modificartimeout função para aceitar funções retornando promessas sem perder seus erros / informações de progresso?

questionAnswers(3)

yourAnswerToTheQuestion