确定函数是否是jQuery Promise

时间:2018-08-20 20:15:42

标签: javascript jquery

假设我有一个页面加载器,它可以运行一个普通函数或一个jQuery AJAX请求。如果AJAX请求成功(例如done),我只想转到下一步;否则,则显示错误(例如fail)。

function runStep(stepText, functionToCall){
   this.setStepText(stepText);
   // call function
   let result = functionToCall();
   // if the function is jquery, wait for the result
   if(result && typeof result.then === 'function'){
       let self = this;
       result.done(function(){ 
           self.goToNextStep();
       }).fail(function(){ 
           self.showFailureMsg();
       });
   }
   // if its a plain old function go to the next step   
   else {
      this.goToNextStep();
   }      
}

我不明白的是;在我调用donefaile的时候,我已经运行了jQuery AJAX请求。那么附加这些处理程序还为时不晚吗?

1 个答案:

答案 0 :(得分:3)

关于Promises的好处是,附加时无所谓。一旦完成,状态将保持不变。

通过这种方式,您可以在应用程序的整个生命周期中传递已解决或被拒绝的Promise,并且仍会调用后期的侦听器。

const pg = Promise.resolve("foo");
const pb = Promise.reject("bar");

pg.then(v => console.log(v));
pb.catch(err => console.error(err));

由于jqXHR对象(即$.ajax() returns)实现了与Promise相同的接口,因此您也可以在需要时附加。

const d = $.Deferred();
const dpr = d.promise();
d.resolve("foo");

dpr.then(v => console.log(v));

setTimeout(() => {
  console.log("Even 3 seconds later it's still foo");
  dpr.then(v => console.log(v));
}, 3000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


考虑以下使用真实XHR的具体示例:

const post = $.ajax("https://jsonplaceholder.typicode.com/posts/1");

post.then(p => {
  // We are in the callback of the request 
  // so we know that it is complete
  console.log(p.title);

  // Let's add another callback when we *think*
  // it should be too late
  post.then(latep => {

    // Still possible
    console.log(p.title)
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>