Ajax javascript 对象内的异步

Ajax async inside a javascript object

我正在构建一个 javascript 对象来处理我的 ajax 功能(错误处理、处理响应)。我的问题是它仅在我在 ajax 请求中设置 async: false 时才有效。在所有其他情况下,结果是未定义的。其他一些人在这里建议,使用 async: false 是一件坏事。所以我的问题是:我可以重写我的代码以避免使用 async: false(不为此添加很多行)。

{extends file="full.tpl"} <!-- SMARTY STUFF -->
{block name=content} <!-- SMARTY STUFF -->
<script type="text/javascript">  
function contentManager(options){

   this.O = options; // var for options
   this.Q; // var for the ajaxresponse
   this.R; // var for the ajaxresponse object JSON.parse(response);

   this.SetupPost = function(){ //[#3] Method which loads the Ajax method
      this.Q = this.AjaxPost(); //[#4] Pass the AjaxPost() return response to this.Q
      this.Q.done(function(response){
         this.R = JSON.parse(response); //[#5] Convert the result to Object
      });
      return this.R; //[#6] Return the result object
   },

   this.AjaxPost = function(){
      return $.ajax({
            type: "POST",
            url: this.O.output_url,
            dataType: this.O.datatype,
            async: false,
            context: this
      });
   },

}

var details = { //Object for parameters - will use inside the contentManager object
           output_url: '{$base}gallery/ajaxadd/', //url uf the ajax call
           data: $(document.getElementById('gallery_name')).serialize(), //data what we want to post (i dont use it now)
           dataType: 'json', //datatype
           output_area: 'apple', //where to put the results if there are any
           errorMsg: { //where to put the error messages if there are any
               Visible: true, //visibility
               Area: 'top' //area to put error messages
           }  
}; // details WILL GO INSIDE contentManager ->> see below

$( document ).ready(function() { //evrything has been loaded
        var cm = new contentManager(details); //[#1] create the object(contentManager) AS (cm) when the page loads
        var result = cm.SetupPost(); //[#2] call the SetupPost method (will return an object, containing the results(object))
        console.log(result); //--> console.log the result object //[#7] There must be the object, but i get only 'undefined', when i dont use the async: false.

});  
</script>
<div id="testarea">
   <form id="testform"> </form>
   <input type="text" name="gallery_name" value="asdasd" id="gallery_name" class="form-control" placeholder="Gallery Name">
</div>
{/block} <!-- SMARTY STUFF -->

使用 Promise 通常是执行异步调用的更简单方法。 看看这个功能:

function callService(url, args) {
    return new Promise(
        function(resolve, reject) {
            var xhr = new XMLHttpRequest();
            xhr.onload = function() {
                var value = xhr.responseText;
                try {
                    resolve(JSON.parse(value));
                }
                catch (ex) {
                    reject("Invalid JSON!");
                }
            };
            xhr.onerror = function() {
                reject("Connexion problem: " + xhr.statusText);
            };
            xhr.open("POST", url, true);
            var params = encodeURIComponent(args);
            xhr.setRequestHeader(
                "Content-type",
                "application/x-www-form-urlencoded");
            xhr.send(params);
        }
    );
}

你可以这样使用它:

callService("http://mywebsite/service.php", "a=6&x=test").then(
    function(data) {
        console.log(data);
    },
    function(err) {
        alert(err);
    }
);

Promise 是主要现代浏览器的一部分。它不是外部图书馆。你可以直接使用它。

这对您的问题有帮助吗?

您应该传递回调,它将在请求完成后调用。

this.Q.done(function(response){
   this.R = JSON.parse(response);
});
return this.R; //[#6] Return the result object

当你 return R 时它是未定义的,因为你传递给 done() 的函数还没有被调用。你可以这样写

this.SetupPost = function(callback){ 
   var req = this.AjaxPost(); 
   req.done(function(response){
      callback(JSON.parse(response)); //invoke your callback
   });
},

并像这样使用:

var cm = new contentManager(details)
cm.SetupPost(function (result) {
    console.log(result);
});