简体   繁体   English

从异步OR同步JavaScript请求返回值

[英]Return value from asynchronous OR synchronous JavaScript request

The function below first performs a synchronous comparison test == 0 , and if it passes, returns some content, and if it doesn't pass, performs an asynchronous request. 下面的函数首先执行同步比较test == 0 ,如果它通过,则返回一些内容,如果没有通过,则执行异步请求。 My intent is for the later to return some other content such as "something from post callback", but know I am doing things way wrong. 我的意图是让后者返回一些其他内容,例如“来自回调后的内容”,但知道我做错了。 Without changing the Ajax request to synchronous, is it possible to do this? 在不将Ajax请求更改为同步的情况下,是否可以执行此操作?

var value = function (test) {
    if (test == 0) {
        return 'value is zero ';
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            return 'something from post callback';
        })
            .done(function (r2) {
            console.log('r2', r2);
            return 'something from done callback';
        });
    }
}(1);

console.log(value);

https://jsfiddle.net/o5kq8he6/2/ https://jsfiddle.net/o5kq8he6/2/

Since you are already returning a promise from the ajax call, then from your synchronous comparison, just return a resolved promise. 由于您已经从ajax调用返回了一个promise,然后从同步比较中返回一个已解决的promise。 Then, both code paths return promises that are resolved with the terminal value and the caller can use the same code to process the result no matter which way it works internally. 然后,两个代码路径都返回使用终端值解析的promise,并且调用者可以使用相同的代码来处理结果,无论它在内部工作的方式如何。 This is a common design pattern for code that is sometimes synchronous and sometimes asynchronous. 这是代码的常见设计模式,有时是同步的,有时是异步的。

var myFunc = function (test) {
    if (test == 0) {
        return $.Deferred().resolve('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }).then(function (r2) {
            console.log('r2', r2);
            // this will be the return value of the promise
            return 'something from ajax finished';
        });
    }
};

myFunc(1).then(function(value) {
    // value is here either way
});

FYI, it does not make sense in your $.post() to use both a success handler function AND a .done() handler. 仅供参考,在$.post()中使用成功处理函数和.done()处理程序是没有意义的。 If you're going to return a promise from the function (which is my recommendation), then you should use only promise handlers, not the success callback. 如果你要从函数中返回一个promise(这是我的推荐),那么你应该只使用promise处理程序,而不是成功回调。

You may also need to understand that it does nothing useful to return a value from the success handler of an ajax call. 您可能还需要了解从ajax调用的成功处理程序返回值没有任何用处。 That return value just goes back into the asynchronous bowels of the ajax infrastructure and is never used by anything. 返回值只会回到ajax基础结构的异步内容中,并且永远不会被任何东西使用。

Make it all async: 使所有异步:

var value = function (test, callback) {
    if (test == 0) {
        callback('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            callback('something from post callback');
        })
            .done(function (r2) {
            console.log('r2', r2);
            callback('something from done callback');
        });
    }
}(1, function(result) { console.log(result); } );

You can simulate an async call for the others and then use a callback for all: 您可以为其他人模拟异步调用,然后对所有人使用回调:

var value = function (test, callback) {
    if (test == 0) {
        callback('value is zero ');
    } else {
        return $.post('/echo/html/', {
            html: 'false ',
            delay: .5
        }, function (r1) {
            console.log('r1', r1);
            callback('something from post callback');
        })
            .done(function (r2) {
            console.log('r2', r2);
            callback('something from done callback');
        });
    }
}(1, myCallback);


function myCallback(result) {
   // here will the result be
}

You can also use setTimeout to actually make the sync calls behave as async calls in case you should need that. 您还可以使用setTimeout实际使同步调用表现为异步调用,以备您需要时使用。

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

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