Javascript 如何在第一次通话后重新调用承诺?

Javascript 如何在第一次通话后重新调用承诺?,javascript,ajax,promise,Javascript,Ajax,Promise,在第一次通话后,我如何重新调用承诺 我遇到了这样一个问题,。然后仅在第一次单击后执行一次,您将无法获得此控制台.log(“Success!”,response)在此后的任何单击中执行。但是我需要它来回收。可能吗 用法: $( document ).ready(function() { get('http://api.icndb.com/jokes/random').then(function(response) { console.log("Success!", res

在第一次通话后,我如何重新调用承诺

我遇到了这样一个问题,
。然后仅在第一次单击后执行一次
,您将无法获得此
控制台.log(“Success!”,response)在此后的任何单击中执行。但是我需要它来回收。可能吗

用法:

$( document ).ready(function() {

    get('http://api.icndb.com/jokes/random').then(function(response) {
        console.log("Success!", response);
      }, function(error) {
        console.error("Failed!", error);
    });

});
承诺功能:

function get(url) {

  // Return a new promise.
  return new Promise(function(resolve, reject) {

      $(".promise").click(function(){

          // do lots of other stuff here...

           // Do the usual XHR stuff
            var req = new XMLHttpRequest();
            req.open('GET', url);

            req.onload = function() {
              // This is called even on 404 etc
              // so check the status
              if (req.status == 200) {
                // Resolve the promise with the response text
                resolve(req.response);
              }
              else {
                // Otherwise reject with the status text
                // which will hopefully be a meaningful error
                reject(Error(req.statusText));
              }
            };

            // Handle network errors
            req.onerror = function() {
              reject(Error("Network Error"));
            };

            // Make the request
            req.send();
      });

  });
}
html


正如我在评论中解释的,承诺只能使用一次。一旦它被解析或拒绝,它的状态将被永久设置,并且它将不再调用现有的
。then()
处理程序。所以,你不能在每次事件发生时都使用你想要调用的承诺。您可能会返回到类似这样的回调,这似乎非常适合这种情况:

$( document ).ready(function() {

    get('http://api.icndb.com/jokes/random', function(response) {
        console.log("Success!", response);
      }, function(error) {
        console.error("Failed!", error);
    });

});

function get(url, success, fail) {

    $(".promise").click(function(){

      // do lots of other stuff here...

       // Do the usual XHR stuff
        var req = new XMLHttpRequest();
        req.open('GET', url);

        req.onload = function() {
          // This is called even on 404 etc
          // so check the status
          if (req.status == 200) {
            // Resolve the promise with the response text
            success(req.response);
          }
          else {
            // Otherwise reject with the status text
            // which will hopefully be a meaningful error
            fail(Error(req.statusText));
          }
        };

        // Handle network errors
        req.onerror = function() {
          fail(Error("Network Error"));
        };

        // Make the request
        req.send();
    });
}

编写自己的promisified
get()
函数没有错,这正是jQuery的
$.ajax()
或Angular的
$http
(以及其他)提供给您的

您只需稍微重新排列代码,以便:

  • get()
    是一个通用工具,与特定事件无关
  • 根据需要从事件处理程序调用
    get()

我在这里所做的就是将代码行移动到不同的顺序。

每次单击都必须创建一个新的承诺,这需要重新构造代码的工作方式。承诺只能使用一次。一旦它被解析,它的状态就再也不能更改了。您已经在使用jQuery了-为什么不直接执行
var get=$.get
?-jQuery的ajax方法已经回报了承诺,并且已经这么做了很多年。我经常尝试使用javascript本机的东西,所以计划在没有jQuery的情况下调用ajax。@tealou是的,但是你正在使用jQuery,为什么要重新发明轮子呢?我要放弃jQuery。谢谢你的回答。我想我只需要将click事件移到函数外部-正如Roamer-1888所建议的那样。@tealou-如果在初始化时只调用一次
get()
,则不必将click处理程序移到函数外部,因为函数所做的是安装click处理程序并设置回调。但是,如果您打算不止一次或在多种情况下使用该函数,则需要对其进行重构,以便更好地重用它的各个部分。谢谢。是的,你是对的。我必须将click事件移到外部,问题就解决了。非常感谢你。
$( document ).ready(function() {

    get('http://api.icndb.com/jokes/random', function(response) {
        console.log("Success!", response);
      }, function(error) {
        console.error("Failed!", error);
    });

});

function get(url, success, fail) {

    $(".promise").click(function(){

      // do lots of other stuff here...

       // Do the usual XHR stuff
        var req = new XMLHttpRequest();
        req.open('GET', url);

        req.onload = function() {
          // This is called even on 404 etc
          // so check the status
          if (req.status == 200) {
            // Resolve the promise with the response text
            success(req.response);
          }
          else {
            // Otherwise reject with the status text
            // which will hopefully be a meaningful error
            fail(Error(req.statusText));
          }
        };

        // Handle network errors
        req.onerror = function() {
          fail(Error("Network Error"));
        };

        // Make the request
        req.send();
    });
}
$(function() {
    function get(url) {
        return new Promise(function(resolve, reject) {
            var req = new XMLHttpRequest();
            req.open('GET', url);
            req.onload = function() {
                if (req.status == 200) {
                    resolve(req.response);
                } else {
                    reject(Error(req.statusText));
                }
            };
            req.onerror = function() {
                reject(Error("Network Error"));
            };
            req.send();
        });
    }
    $(".promise").click(function() {
        // do lots of other stuff here...
        get('http://api.icndb.com/jokes/random').then(function(response) {
            console.log("Success!", response);
        }, function(error) {
            console.error("Failed!", error);
        });
    });
});