在JavaScript中,如何在超时中包装一个promise? [英] in JavaScript, how to wrap a promise in timeout?

查看:100
本文介绍了在JavaScript中,如何在超时中包装一个promise?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是使用deffered / promise实现某些异步函数超时的常见模式:

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

// 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();
}

现在我们可以执行一些名为 myFunc <的异步函数/ code>并处理超时:

Now we can execute some asynchronous function called myFunc and handle timeout:

// 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' );
    }
);

好的,让我们来讲一下这个故事吧!想象一下, myFunc 本身会返回一个承诺(注意:承诺不推迟,我无法更改):

OK, let's make a twist in this story! Imagine that the myFunc itself returns a promise (NOTE: promise NOT deferred and I can't change it):

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();
}

现在如果我换 myFunc 超时中,我将失去处理不同于超时的错误的能力。如果 myFunc 发出进度事件,我也会松开它。

Now if I wrap myFunc in timeout, I will loose the ability to handle errors different then timeout. If myFunc emit progress events, I will loose this as well.

所以问题是:如何修改 timeout 函数所以它可以接受函数返回promises而不会丢失它们的错误/进度信息吗?

So the question is: how to modify timeout function so it can accept functions returning promises without loosing their errors/progress information?

推荐答案

function timeout(funct, args, time) {
    var deferred = new jQuery.Deferred(),
        promise = funct.apply(null, args);

    if (promise) {
        $.when(promise)
            .done(deferred.resolve)
            .fail(deferred.reject)
            .progress(deferred.notify);
    }

    setTimeout(function() {
        deferred.reject();
    }, time);

    return deferred.promise();
}

这篇关于在JavaScript中,如何在超时中包装一个promise?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆