【问题标题】:Converting to the ajax async false alternative because of depreciation由于折旧而转换为 ajax async false 替代方案
【发布时间】:2018-01-02 13:44:17
【问题描述】:

我已经对这个问题进行了研究并找到了一些解决方案。然而,并不是每个人都有效。据我了解, async false 会造成 UI 块,这不应该。我可以使用覆盖,直到 ajax 请求完成并且请求成功时,隐藏覆盖。

这是我在getNewQuote() 函数中使用回调参数的尝试(只是其中的一小部分):

var getNewQuote = function(callback) {
  var quote = {};
  setTimeout(function() {
    quote.text = 'Example';
    quote.author = 'Example';
    callback();
    return quote;
  }, 4000);
};

getNewQuote(function() {
  console.log("DONE");
  var getRandomColor = function() {
  var colors = [
      "#ff9966",
      "#7f00ff",
      "#396afc",
      "#0cebeb",
      "#06beb6",
      "#642b73",
      "#36d1dc",
      "#cb356b",
      "#3a1c71",
      "#ef3b36",
      "#159957",
      "#000046",
      "#007991",
      "#56ccf2",
      "#f2994a",
      "#e44d26",
      "#4ac29a",
      "#f7971e",
      "#34e89e",
      "#6190e8",
      "#3494e6",
      "#ee0979"
    ],
    randomNumber = Math.floor(Math.random() * colors.length);
  return colors[randomNumber];
};

var updateText = function($t, qt) {

  var twitter = "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=";
  twitter += '"' + qt.text + '" ';
  twitter += qt.author;

  var tumblr = "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=";
  tumblr += qt.author;
  tumblr += "&content=";
  tumblr += qt.text;
  tumblr += "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button";

  var $icon = $("<i class='fa fa-quote-left'>")
    .prop("aria-hidden", true);

  $t.find(".quote-text").html("").append($icon, qt.text);
  $t.find(".quote-author").html("- " + qt.author);
  $("#tweet-quote").attr("href", twitter);
  $("#tumblr-quote").attr("href", tumblr);
};

var calcNewHeight = function(q) {
  var $temp = $("<div>", {
    class: "quote-container temp",
  }).appendTo($("body"));
  $temp.append($("<div>", {
    class: "quote-text"
  }), $("<div>", {
    class: "quote-author"
  }));
  updateText($temp, q);
  var h = $temp.height() + 40;
  $temp.remove();
  return h;
};

var changeColor = function(newColor) {
  $("body, .button:not(#new-quote)").animate({
    backgroundColor: newColor
  });
  $("#new-quote").animate({
    color: newColor
  });
  $(".quote-text, .quote-author").css("color", newColor);
  if ($("#modStyle").length === 0) {
    $("head").append(
      "<style id='modStyle'>#new-quote:before {background:" + newColor + ";}</style>"
    );
  } else {
    $("head style#modStyle").html("#new-quote:before {background:" + newColor + ";}");

  }
};

var getQuote = function() {
  var nq, nc, nh = 0;

      nq = getNewQuote();
      nc = getRandomColor();
      nh = calcNewHeight(nq);
  
      $(".quote-container").children().css("opacity", 0);
      changeColor(nc);
  
      $(".quote-container, #new-quote").animate({
        height: nh,
      }, {
        duration: 1000,
        queue: false
      });

      $(".quote-container").animate({
        padding: "2.5em"
      }, {
        duration: 1000,
        queue: false
      });

      $("#new-quote").animate({
        padding: "2.5em .75em"
      }, {
        duration: 1000,
        queue: false
      });
  
      updateText($(".quote-container"), nq);
      $(".quote-container").children().fadeTo(750, 1);
};

  $("#new-quote").on("click", getQuote);
  $(".quote-container, #new-quote").css({
    visibility: "visible",
    height: 0
  });
  $("#new-quote").css("padding", "0 .75em");
  getQuote();
});
html,
body {
  height: 100%;
  width: 100%;
}

body {
  margin: 0;
  padding: 0;
  background: #333;
  color: #333;
  font-family: sans-serif;
}

.v-wrap {
  height: 100%;
  text-align: center;
}

.v-wrap:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  width: 0;
  height: 100%;
}

.quote-container {
  width: 31.25rem;
  background: #fff;
  margin: 0;
  display: inline-block;
  vertical-align: middle;
  border-radius: 0.1875rem;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  visibility: hidden;
  padding: 0 2.5rem;
}

.quote-text {
  font-size: 1.625rem;
}

.quote-text i {
  margin-right: 0.6rem;
}

.quote-text p {
  display: inline;
}

.quote-author {
  font-size: 1rem;
  margin: 0 0.4rem 2rem 0;
  text-align: right;
}

.button {
  padding: 0.75rem;
  text-align: center;
  font-size: 1rem;
  color: #fff;
  border-radius: .1875rem;
  display: inline-block;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.button:not(#new-quote):hover {
  opacity: .8 !important;
}

.button:not(#new-quote) {
  min-width: 1rem;
  min-height: 1rem;
}

.button i {
  vertical-align: middle;
}

#new-quote {
  white-space: nowrap;
  writing-mode: vertical-lr;
  height: 50%;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  vertical-align: middle;
  background: #fff !important;
  margin: 0;
  position: relative;
  right: 0.25625rem;
  color: #333;
  visibility: hidden;
}

#new-quote:before {
  content: "";
  position: absolute;
  height: 100%;
  width: 0.0625rem;
  bottom: 0;
  left: 0;
  visibility: hidden;
  -webkit-transform: scaleY(0);
  transform: scaleY(0);
  -webkit-transition: all .3s ease-in-out;
  transition: all .3s ease-in-out;
}

#new-quote:hover:before {
  visibility: visible;
  -webkit-transform: scaleY(1);
  transform: scaleY(1);
}

footer {
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

footer a {
  text-decoration: none;
  color: #fff;
  position: relative;
}

footer a:before {
  content: "";
  position: absolute;
  width: 100%;
  height: .0625rem;
  bottom: 0;
  left: 0;
  background: #fff;
  visibility: hidden;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transition: all .3s ease-in-out 0s;
  transition: all .3s ease-in-out 0s;
}

footer a:hover:before {
  visibility: visible;
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="v-wrap">
  <div class="quote-container" style="">
    <div class="quote-text">
    </div>
    <div class="quote-author"></div>
    <a id="tweet-quote" class="button"><i class="fa fa-twitter"></i></a>
    <a id="tumblr-quote" class="button"><i class="fa fa-tumblr"></i></a>
  </div>
  <div id="new-quote" class="button">New quote</div>
  <footer>
    <a href="https://codepen.io/Kestis500">Created by LukasLSC</a>
  </footer>
</div>

代码输出: 如你所见,ajax 并不成功

Uncaught TypeError: callback is not a function and Uncaught TypeError: Cannot read property 'text' of undefined (only in the stack sn-p).

我发现如果我删除 getQuote(); 函数调用,这个错误就会消失。但是,我需要调用它,否则我的项目将无法正常工作。我也尝试使用return $.ajax,但有一条return quote 行,所以我无法使用它。完整代码可以在 codepen 上找到:https://codepen.io/Kestis500/pen/ZvyxKB?editors=0110。


然后我切换到使用 jQuery 承诺的另一种方法,并在此线程中使用了信息:https://stackoverflow.com/a/40658281/8889739。完整代码:https://codepen.io/Kestis500/pen/qpjxoq?editors=0110.

var MyFirstFunction = function() {
  var getNewQuote = function(callback) {
    var quote = {};
    setTimeout(function() {
      quote.text = 'Example';
      quote.author = 'Example';

      return quote;
    }, 4000);
  };
}

var MySecondFunction = function() {
  console.log("DONE");
  var getRandomColor = function() {
    var colors = [
        "#ff9966",
        "#7f00ff",
        "#396afc",
        "#0cebeb",
        "#06beb6",
        "#642b73",
        "#36d1dc",
        "#cb356b",
        "#3a1c71",
        "#ef3b36",
        "#159957",
        "#000046",
        "#007991",
        "#56ccf2",
        "#f2994a",
        "#e44d26",
        "#4ac29a",
        "#f7971e",
        "#34e89e",
        "#6190e8",
        "#3494e6",
        "#ee0979"
      ],
      randomNumber = Math.floor(Math.random() * colors.length);
    return colors[randomNumber];
  };

  var updateText = function($t, qt) {

    var twitter = "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=";
    twitter += '"' + qt.text + '" ';
    twitter += qt.author;

    var tumblr = "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=";
    tumblr += qt.author;
    tumblr += "&content=";
    tumblr += qt.text;
    tumblr += "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button";

    var $icon = $("<i class='fa fa-quote-left'>")
      .prop("aria-hidden", true);

    $t.find(".quote-text").html("").append($icon, qt.text);
    $t.find(".quote-author").html("- " + qt.author);
    $("#tweet-quote").attr("href", twitter);
    $("#tumblr-quote").attr("href", tumblr);
  };

  var calcNewHeight = function(q) {
    var $temp = $("<div>", {
      class: "quote-container temp",
    }).appendTo($("body"));
    $temp.append($("<div>", {
      class: "quote-text"
    }), $("<div>", {
      class: "quote-author"
    }));
    updateText($temp, q);
    var h = $temp.height() + 40;
    $temp.remove();
    return h;
  };

  var changeColor = function(newColor) {
    $("body, .button:not(#new-quote)").animate({
      backgroundColor: newColor
    });
    $("#new-quote").animate({
      color: newColor
    });
    $(".quote-text, .quote-author").css("color", newColor);
    if ($("#modStyle").length === 0) {
      $("head").append(
        "<style id='modStyle'>#new-quote:before {background:" + newColor + ";}</style>"
      );
    } else {
      $("head style#modStyle").html("#new-quote:before {background:" + newColor + ";}");

    }
  };

  var getQuote = function() {
    var nq, nc, nh = 0;

    nq = getNewQuote();
    nc = getRandomColor();
    nh = calcNewHeight(nq);

    $(".quote-container").children().css("opacity", 0);
    changeColor(nc);

    $(".quote-container, #new-quote").animate({
      height: nh,
    }, {
      duration: 1000,
      queue: false
    });

    $(".quote-container").animate({
      padding: "2.5em"
    }, {
      duration: 1000,
      queue: false
    });

    $("#new-quote").animate({
      padding: "2.5em .75em"
    }, {
      duration: 1000,
      queue: false
    });

    updateText($(".quote-container"), nq);
    $(".quote-container").children().fadeTo(750, 1);
  };

  $("#new-quote").on("click", getQuote);
  $(".quote-container, #new-quote").css({
    visibility: "visible",
    height: 0
  });
  $("#new-quote").css("padding", "0 .75em");
  getQuote();
}

MyFirstFunction().done(MySecondFunction);
html,
body {
  height: 100%;
  width: 100%;
}

body {
  margin: 0;
  padding: 0;
  background: #333;
  color: #333;
  font-family: sans-serif;
}

.v-wrap {
  height: 100%;
  text-align: center;
}

.v-wrap:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  width: 0;
  height: 100%;
}

.quote-container {
  width: 31.25rem;
  background: #fff;
  margin: 0;
  display: inline-block;
  vertical-align: middle;
  border-radius: 0.1875rem;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  visibility: hidden;
  padding: 0 2.5rem;
}

.quote-text {
  font-size: 1.625rem;
}

.quote-text i {
  margin-right: 0.6rem;
}

.quote-text p {
  display: inline;
}

.quote-author {
  font-size: 1rem;
  margin: 0 0.4rem 2rem 0;
  text-align: right;
}

.button {
  padding: 0.75rem;
  text-align: center;
  font-size: 1rem;
  color: #fff;
  border-radius: .1875rem;
  display: inline-block;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.button:not(#new-quote):hover {
  opacity: .8 !important;
}

.button:not(#new-quote) {
  min-width: 1rem;
  min-height: 1rem;
}

.button i {
  vertical-align: middle;
}

#new-quote {
  white-space: nowrap;
  writing-mode: vertical-lr;
  height: 50%;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  vertical-align: middle;
  background: #fff !important;
  margin: 0;
  position: relative;
  right: 0.25625rem;
  color: #333;
  visibility: hidden;
}

#new-quote:before {
  content: "";
  position: absolute;
  height: 100%;
  width: 0.0625rem;
  bottom: 0;
  left: 0;
  visibility: hidden;
  -webkit-transform: scaleY(0);
  transform: scaleY(0);
  -webkit-transition: all .3s ease-in-out;
  transition: all .3s ease-in-out;
}

#new-quote:hover:before {
  visibility: visible;
  -webkit-transform: scaleY(1);
  transform: scaleY(1);
}

footer {
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

footer a {
  text-decoration: none;
  color: #fff;
  position: relative;
}

footer a:before {
  content: "";
  position: absolute;
  width: 100%;
  height: .0625rem;
  bottom: 0;
  left: 0;
  background: #fff;
  visibility: hidden;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transition: all .3s ease-in-out 0s;
  transition: all .3s ease-in-out 0s;
}

footer a:hover:before {
  visibility: visible;
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="v-wrap">
  <div class="quote-container" style="">
    <div class="quote-text">
    </div>
    <div class="quote-author"></div>
    <a id="tweet-quote" class="button"><i class="fa fa-twitter"></i></a>
    <a id="tumblr-quote" class="button"><i class="fa fa-tumblr"></i></a>
  </div>
  <div id="new-quote" class="button">New quote</div>
  <footer>
    <a href="https://codepen.io/Kestis500">Created by LukasLSC</a>
  </footer>
</div>

代码输出: 它破坏了一切,灰屏是因为默认的 codepen 背景

未捕获的类型错误:无法读取未定义的属性“完成”

【问题讨论】:

  • 请用minimal reproducible example 更新您的问题,证明问题(强调minimal),最好是使用堆栈片段(@ 987654342@ 工具栏按钮;here's how to do one)。您的第一个代码块清楚地显示了将函数作为 callback 参数传入,因此不应生成您引用的错误。
  • 好的,请稍等。
  • 我不能因为 CORS:无法加载 quotesondesign.com/wp-json/…:“Access-Control-Allow-Origin”标头的值“null”不等于提供的原点.因此,不允许访问 Origin 'null'。
  • 您可以通过setTimeout 模拟ajax。 Ajax 与您的问题无关。您的问题是关于异步操作的。
  • 现在看看。

标签: javascript jquery html css ajax


【解决方案1】:

您正在使用异步操作回调中的return。这只是设置该回调的返回值(在 setTimeout 或 XHR 的回调的情况下被忽略),它不会设置您的函数的返回值。

您不能从您的函数返回值,这就是您添加回调的原因。而是:

var getNewQuote = function(callback) {
  var quote = {};
  setTimeout(function() {
    quote.text = 'Example';
    quote.author = 'Example';
    callback(quote); // <====
  }, 4000);
};

...并使用回调的参数,例如:

getNewQuote(function(quote) {
    // Use quote here...
});

现场示例:

var getNewQuote = function(callback) {
  var quote = {};
  setTimeout(function() {
    quote.text = 'Example';
    quote.author = 'Example';
    callback(quote); // <====
  }, 1000);
};

getNewQuote(function(quote) {
    console.log("quote:", quote);
});

【讨论】:

  • 它给出了两个错误:未捕获的类型错误:回调不是函数和未捕获的类型错误:无法读取未定义的属性“文本”。 Codepen 链接:codepen.io/Kestis500/pen/QagrKv?editors=0110.
  • 我有一个问题。我怎样才能写一行,以便当用户单击 #new-quote 按钮时, getNewQuote() 执行? $("#new-quote").on("click", getNewQuote); 不起作用。
  • @LukasNaujokaitis:您需要向它传递一个对引用执行某些操作的回调,例如:$("#new-quote").on("click", function() { getNewQuote(function(quote) { /* do something with it */}); });
  • 是的,我知道,但是 getNewQuote() 函数很长(比如 150 行)。我怎样才能从这行的第一个这个函数执行中重用它:getNewQuote(function(quote) { // Use quote here... });,所以我不需要再写所有这 150 行?
  • 也许我可以创建另一个函数?
猜你喜欢
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 2015-07-10
相关资源
最近更新 更多