然后调用函数时如何触发回调?

时间:2019-07-12 06:59:21

标签: javascript promise

我已经找到了一个自定义的js promise实现并试图理解它,但是我无法弄清楚如何立即执行或触发回调,因为promise的定义被立即调用,但是我们只是在实现中推送到回调数组中< / p>

https://playcode.io/364624?tabs=script.js,preview,console

function myPromise(definitionFunction){
  this.thenCallbacks = [];
  this.status = 'pending';
  this.value = undefined;

  definitionFunction(resolver.bind(this),rejector.bind(this));

  function resolver(value)
  {
    this.status = 'resolved';
    this.value = value;
    this.thenCallbacks.forEach(function(func){
      console.log(func);
     this.value =  func(this.value);
    },this);
  }

  function rejector(value)
  {

  }
}

myPromise.prototype.then = function(successCallback,errorCallback){

  this.thenCallbacks.push(successCallback);
  return this;
}


var test = new myPromise(function(resolve,reject){

     var xhttp = new XMLHttpRequest();
     var url = "https://jsonmock.hackerrank.com/api/stocks/search?page="+1;
     xhttp.open("GET",url , true);
     xhttp.onload = function() {
        if (this.readyState == 4 && this.status == 200) {
          resolve(this.responseText);
        }
        else
        {
          reject({
          status: this.status,
          statusText: xhttp.statusText
        })
        }
      };
    xhttp.onerror = function() {
       reject({
        status: this.status,
        statusText: xhr.statusText
      });
    }
    xhttp.send();

  });

  test.then((response)=>'kiran').then((resp)=>{return{name:'kiran'}}).then((resp)=>console.log(resp));

有人可以清除吗

1 个答案:

答案 0 :(得分:1)

首先,这是对诺言的一种特别糟糕的实现,因为它会做各种错误的事情:

  1. 当前执行线程完成后,它不会异步解析,这可能导致时序问题不一致。
  2. 它不支持与.then().then()的正确链接,其中.then()返回一个新的Promise,因此第二个.then()仅在第一个Promise解决后才调用它的处理程序。
  3. 它不支持正确的链接,其中.then()回调处理程序可以返回将被插入到链中的Promise
  4. 它不会调用在解决诺言之后添加的.then()处理程序。
  5. 它不会锁定诺言的状态,因此无法更改。
  6. 它不会在执行程序或.then().catch()处理程序中捕获同步异常,并将它们转换为被拒绝的承诺。

为获得更好的实施效果,建议您参考以下代码:https://www.promisejs.org/implementing/,该代码显然始于stackoverflow answer,因为这样可以使您更好地了解实现诺言所涉及的内容。

  

我无法弄清楚如何立即执行回调或触发回调,因为promise的定义会立即被调用,但我们只是在实现时才将其推入回调数组中

.then()的作用是注册一个回调(保存),以便将来可以调用它。因此,很自然的是,它只会向数组添加回调,然后可以在将来的某个时间(例如实现诺言时)执行该数组中的回调。

在此实现中,definitionFunction()是promise执行者。这是传递给new Promise(fn)构造函数的回调,应该立即调用它。

.then()回调然后存储在数组中。

然后,稍后在调用执行程序中的resolver()函数时,它将使用this.thenCallbacks.forEach()迭代该数组并调用该数组中的每个函数。

但是,此实现在许多方面无法正常工作。如果resolver()立即被调用,则.thenCallbacks数组将为空,因为尚未在promise中调用.then(),然后在稍后的某个时间调用.then()。已经解决的承诺,它永远不会调用回调。

正如我在评论中所说,我不想再花时间讨论这种有缺陷的承诺实现的工作原理。我试图回答您的直接问题,并引导您朝着更好,更准确,更完整的承诺实施方向发展,您可以继续学习。这个有各种各样的问题,所以,我认为,花更多的时间了解它的工作原理是不值得的。

您还可以花一些时间阅读Promises/A+ specification,这实际上并不容易阅读或理解。