使用async/await与$.ajax

3
这是我第一次尝试使用异步JavaScript。我已经尝试过连接所有关于Promise的版本,但都无法成功编写,以使我的字符串返回(即$.Deferred、async/await、Promise、回调函数、依赖于.done)。虽然async:false作为ajax变量可以工作,但我试图避免采用我理解中的不良实践。我很想使用async/await,因为它非常简洁,但现在我愿意尝试任何有效的方法。我怀疑我正在以不正确的方式利用$.ajax返回。
非常感谢能够获得字符串wholename(随机生成的名字和姓氏)的有效返回,对于我自己学习的几个版本的示例,更加感激!
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
    });
}

预期结果是什么? - guest271314
异步函数 makeName(sex) { var thexml = await getPromiseName(sex); // 移除 thexml.done(function(xml) { // fini // 注意:makeName 现在将返回一个 Promise } - Jaromanda X
@JaromandaX 谢谢,我已经能够使用async返回chrome显示的[object Promise],但是如何获取似乎隐藏在Promise中的字符串呢? - Michael VanLaanen
var thexml = await getPromiseName(sex); 在这一点上,我认为thexml不会是一个Promise...然而,由于您正在使用jQuery的糟糕的Promise替代方案,您的结果可能会有所不同。 - Jaromanda X
2个回答

1

以下是我的建议。这是测试数据,因此名称没有意义,但您只需根据上面的代码更改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);


0

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

如果你想手动找出ajax是否成功发送,你必须用计时器循环它的状态并检查成功状态 - 这是不推荐的。

你的代码在同步模式下工作的原因是,整个javascript会冻结,直到消息得到响应 - 这也是不推荐的 =)

工作中的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);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接