in JavaScript, how to wrap a promise in timeout?

后端 未结 3 1768
清酒与你
清酒与你 2021-02-12 14:05

It\'s a common pattern to implement timeout of some asynchronous function, using deffered/promise:

// Create a Deferred and return its Promise
function timeout(f         


        
3条回答
  •  無奈伤痛
    2021-02-12 14:16

    You should always promsiify at the lowest level possible. Let's start from the basics.

    I'll use jQuery promises here, but this should really be done with a stronger library like Bluebird Let's start simple, by creating our delay as:

    function delay(ms){
        var d = $.Deferred();
        setTimeout(function(){ d.resolve(); }, ms);
        return d.promise();
    }
    

    Note delay doesn't do anything surprising, all our delay function does is cause a delay of ms milliseconds.

    Now, for your library, we want to create a version of doSomething that works with promises:

     superImportantLibrary.doSomethingAsync = function(){
         var d = $.Deferred();
         superImportantLibrary.doSomething(function(data){ d.resolve(data); });
         return d.promise();
     };
    

    Note both our delay and doSomethingAsync functions both do just one thing. Now the fun begins.

    function timeout(promise,ms){
        var timeout = delay(ms); // your timeout
        var d = $.Deferred();
        timeout.then(function(){ d.reject(new Error("Timed Out")); });
        promise.then(function(data){ d.resolve(data); });
        return d.promise();
    }
    
    timeout(superImportantLibrary.doSomethingAsync(),1000).then(function(data){
         // handle success of call
    }, function(err){
         // handle timeout or API failure.
    });
    

    Now in Bluebird, this whole code would have been:

    superImportantLibrary.doSomethingAsync().timeout(1000).then(function(){
        // complete and did not time out.
    });
    

提交回复
热议问题