【问题标题】:Using async / await with $.ajax将 async / await 与 $.ajax 一起使用
【发布时间】:2017-09-27 02:47:08
【问题描述】:

这是我第一次尝试使用异步 javascript。我已经尝试连接我能找到的所有承诺的化身,但未能成功编写它们以使我的字符串返回(即 $.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
    });
}

【问题讨论】:

  • 预期结果是什么?
  • async function makeName(sex) { .... var thexml = await getPromiseName(sex); ... 删除 thexml.done(function(xml) { ... fini ... 注意:makeName 现在将返回一个 Promise
  • @JaromandaX 谢谢,我已经能够使用异步返回 chrome 显示为 [object Promise] 的内容,但是我如何获得明显隐藏在 Promise 中的字符串?
  • var thexml = await getPromiseName(sex); 在这一点上我认为 thexml 不会是 Promise ...但是,由于您使用 jQuery 的 Promises 的糟糕借口,您的里程可能会有所不同

标签: javascript jquery ajax asynchronous


【解决方案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);

【讨论】:

    【解决方案2】:

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

    如果您想手动确定是否成功发送了 ajax,您必须使用计时器循环它的状态并检查成功状态 - 不推荐。

    您的代码在 sync 模式下工作的原因是,整个 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);
    });
    

    【讨论】:

      猜你喜欢
      • 2017-11-05
      • 2019-04-15
      • 2014-06-19
      • 2018-01-14
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多