2017-09-27 243 views
1

这是我第一次尝试使用异步JavaScript。我已经试过把我能找到的承诺的每一个化身都联系起来,但是还没有能够成功地写出它们来让我的字符串返回(即$ .Deferred,async/await,Promise,callbacks,依靠.done)。异步:false作为ajax变量的作品,但我试图避免解决我所知道的是不好的做法。我很乐意使用异步/等待,因为它非常简洁,但在这一点上,我为任何有效的工作而努力。我有一个怀疑,我试图以不正确的方式利用$ .ajax返回。

非常感谢字符串全名(一个随机的姓和名)的工作返回,为我自己的教育的几个版本的例子更赞赏!

function Actor(gender, name) { 
if (gender == "" || gender == undefined) {this.gender = "female";} else this.gender = gender;   
if (name == "" || name == undefined) {this.name = makeName(this.gender);} else this.name = name; 
} 

function getPromiseName(sex) { 
    return promise = $.ajax({ 
     type: "GET", 
     url: "TMxml.xml", 
     dataType: "xml"//, 
     //async: false //this works for returns, but is apparently bad practice 
    }); 
} 

function makeName(sex) { 
    var fnames = []; 
    var lnames = []; 

    var thexml = getPromiseName(sex); 

    thexml.done(function(xml) { 
     if (sex == "male") { 
      $(xml).find('malename').children().each(function(){ 
       fnames.push($(this).text()); 
      }); 
     } 
     if (sex == "female") { 
      $(xml).find('femalename').children().each(function(){ 
       fnames.push($(this).text()); 
      }); 
     } 
     $(xml).find('lastname').children().each(function(){ 
       lnames.push($(this).text()); 
      }); 

     wholename = fnames[Math.floor(Math.random() * fnames.length)] + " " + lnames[Math.floor(Math.random() * lnames.length)]; 
     alert("wholename = " + wholename); //successfully alerts a randomized name 
     return wholename; //but returns undefined, or [object Promise] when using async/await 
    }); 
} 
+0

什么是预期的结果? – guest271314

+0

'异步函数makeName(sex){'....'var thexml = await getPromiseName(sex);'... remove'thexml.done(function(xml){'... fini ...注意:'' makeName'现在会返回一个Promise –

+0

@JaromandaX谢谢你,我已经能够使用async返回什么chrome显示为[object Promise],但是如何获得字符串显然隐藏在Promise中? –

回答

0

你做错了。你必须明白,当你使用异步模式时,你必须使用回调函数来触发你想要的功能。

如果你想手动发现被发现ajax成功,你必须循环它的状态与计时器和检查成功状态 - 这是不推荐。

你的代码在sync模式下工作的原因是,JavaScript的冻结,直到消息回应全 - 这是不是也recomended =)

工作AJAX功能:

function SendAjax($url_mode, $data_serialize, $print_container, $callback_function) { 
     $options = { 
      type: "GET", 
      url: $url_mode, 
      data: $data_serialize, 
      dataType: "xml", 
      success: function (msg) { 
       if ($print_container !== '') { 
        $print_container.html(msg); 
       } 
       if (typeof $callback_function !== "undefined") { 
        $callback_function(msg); 
       } 
      }, 
      error: function (xhr, str) { 
       alert('Error: ' + xhr.responseCode); 
      } 
     }; 
     $.ajax($options); 
    } 

调用SendAjax函数:

$(document).delegate(".btn-grid", "click", function() { 
    SendAjax("TMxml.xml", "?any_key=true", $(".print-container-if-needed-or-set-null"), $Callback_function_like_your_makeName_function); 
}); 
0

这是我的建议。这是测试数据,所以名称没有意义,但是当然,您只需根据上面的代码更改url,getRandomName函数和doStuffWithActor函数。 (正如你所看到的,我会建议保持取逻辑和演员初始化逻辑作为单独地:)

class Actor { 
 
    constructor(name, gender) { 
 
    this.name = name; 
 
    this.gender = gender; 
 
    } 
 
} 
 

 
Array.prototype.sample = function() { 
 
    if (!this.length) return null; 
 
    const randIdx = Math.floor(Math.random() * this.length); 
 
    return this[randIdx]; 
 
}; 
 

 
const createActor = async (url, name, gender, callback) => { 
 
    gender = gender || 'female'; 
 
    if (!name) { 
 
    const response = await fetch(url); 
 
    const data = await response.text(); 
 
    name = getRandomName(data, gender); 
 
    } 
 
    const actor = new Actor(name, gender); 
 
    if (callback) callback(actor); 
 
}; 
 

 
const getRandomName = (xmlData, gender) => { 
 
    const names = xmlData.split(/\s+/); 
 
    const femaleNames = names.slice(0, names.length/2); 
 
    const maleNames = names.slice(names.length/2); 
 
    return gender === 'female' ? femaleNames.sample() : maleNames.sample(); 
 
}; 
 

 
const doStuffWithActor = (actor) => { 
 
    console.log('Actor name:', actor.name); 
 
    console.log('Actor gender:', actor.gender); 
 
    console.log('\n'); 
 
}; 
 

 
createActor('https://httpbin.org/xml', '', '', doStuffWithActor); 
 
createActor('https://httpbin.org/xml', '', 'male', doStuffWithActor);