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

下面的函数首先执行同步比较test == 0 ,如果它通过,则返回一些内容,如果没有通过,则执行异步请求。 我的意图是让后者返回一些其他内容,例如“来自回调后的内容”,但知道我做错了。 在不将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/

由于您已经从ajax调用返回了一个promise,然后从同步比较中返回一个已解决的promise。 然后,两个代码路径都返回使用终端值解析的promise,并且调用者可以使用相同的代码来处理结果,无论它在内部工作的方式如何。 这是代码的常见设计模式,有时是同步的,有时是异步的。

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

仅供参考,在$.post()中使用成功处理函数和.done()处理程序是没有意义的。 如果你要从函数中返回一个promise(这是我的推荐),那么你应该只使用promise处理程序,而不是成功回调。

您可能还需要了解从ajax调用的成功处理程序返回值没有任何用处。 返回值只会回到ajax基础结构的异步内容中,并且永远不会被任何东西使用。

使它全部异步:

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

您可以为其他人模拟异步调用,然后对所有人使用回调:

 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 } 

您还可以使用setTimeout实际使同步调用表现为异步调用,以备您需要时使用。