简体   繁体   English

不支持超时时如何实现javascript同步xmlhttprequest?

[英]How can I achieve javascript sync xmlhttprequest with timeout when it is not supported?

I have searched high and low for alternatives (Promise, async calls, etc) but couldn't yet find a solution that would work. 我在上下搜索了其他选择(Promise,异步调用等),但仍找不到可行的解决方案。

I have a fairly typical situation like: 我有一个非常典型的情况,例如:

blockingCallBackFunctionFor3rdPartyLibraryAPI(url)
{
    responseCode = cloudLookupCall(url); // async or sync call over the web
    if (responseCode == "Deny")
    {
        // Return "Deny" URL decision to external library/API
    }

    // Return default "Allow" decision
}

function cloudLookupCall(url)
{
    var hdl = new XMLHttpRequest();
    hdl.open(method, url, true/false); // true/false based on async/sync

    // use standard XHR stuff to get responseText
    return responseText;
}

Now: 现在:

  1. If I used ASYNC calls with promise, callbacks whatever, I still need to return some decision to the 3rd party library rightaway because a) JS doesn't support sleeping/waiting, b) I can't use a callback from the async onload() because by that time the 3rd party API already moved on to other URLs 如果我使用带承诺的ASYNC调用,回调等功能,我仍然需要立即向第三方库返回一些决定,因为a)JS不支持睡眠/等待,b)我不能使用异步onload的回调( ),因为到那时为止,第三方API已移至其他网址
  2. If I instead use SYNC calls I run the risk of blocking indefinitely. 如果我改用SYNC调用,则可能会无限期地阻塞。 I am already using timeouts on the web cloud handler so it doesn't take too long and also handling onerror(), but still worry that the sync call could just stay stuck for too long. 我已经在Web云处理程序上使用超时,因此它不会花费太长时间,而且也处理onerror(),但仍然担心同步调用可能会停留太长时间。

I just don't get why the JS implementation decided to not support timeouts for sync calls when that's exactly where you seem to need it the most (to avoid hanging the browser perpetually). 我只是不明白为什么JS实现决定在您似乎最需要同步的地方决定不支持同步调用的超时(以避免永久挂起浏览器)。

I have read a ton of forum responses that suggest Promise and async callbacks - but please note above why those will not work - I need an action rightaway OR I need a way to make JS wait. 我已经阅读了很多论坛建议的Promise和异步回调,但请在上面说明为什么这些回调将不起作用-我需要立即采取措施,或者需要让JS等待的方法。 I can't not-wait and not-reply with an action as well. 我也迫不及待地也没有采取行动。

I am fairly convinced at this point that I am stuck with SYNC calls but what to see what the state of the art is in ensuring it does not block perpetually (and ASYNC is not an alternative). 在这一点上,我相当有信心地说,我坚持使用SYNC调用,但是要了解如何确保不永久阻塞SYNC(不是ASYNC的替代方案),这是什么现状。 Would making sure that my web php handler timeout in 1 second using set_time_limit() solve the issue of indefinitely hanging? 使用set_time_limit()确保我的Web php处理程序超时在1秒内解决无限期挂起的问题吗?

If possible try to add a function as parameter to the cloudLookupCall() : 如果可能,请尝试向cloudLookupCall()添加function作为参数:

function cloudLookupCall(func){
    // your stuff here

    // and when it's needed for you to callback
    if (typeof func === 'function'){
        func();
    }
}

Then in your script: 然后在您的脚本中:

responseCode = cloudLookupCall(function(data){
    // continue here
});

If that doesn't work this is a wrapper I use as backup when callbacks or promises are not available and I need to fallback using the timeout functionality: 如果那不起作用,这是一个包装,当回调或promise不可用时,我将其用作备份,并且需要使用timeout功能进行后备:

// @param (callback): function to be run when done
// @param (delay): integer in milliseconds
// @param (id): string value of a unique event id
delayedEvent: (function () {
    var timers = {},
        defEvent = cfg.events;

    return function (callback, delay, id) {
        delay = delay || 1000;
        id = id || 'some id';

        if (timers[id]) {
            clearTimeout(timers[id]);
        }

        timers[id] = setTimeout(callback, delay);
    };
})(),

You can use it like this: 您可以像这样使用它:

responseCode = cloudLookupCall();

delayedEvent(function(){
    if (responseCode === "Deny"){
        // continue here
    }
}, 1000, 'cloudlookup');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM