首页 > 解决方案 > 调用 then 函数时如何触发回调?

问题描述

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

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));

有人可以清除这个吗

标签: javascriptpromise

解决方案


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

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

为了获得更好的实现,我建议您查阅以下代码:https ://www.promisejs.org/implementing/这显然是从这个stackoverflow 答案开始的,因为这将使您更好地了解实现承诺所涉及的内容.

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

什么.then()是注册一个回调(保存它),以便将来可以调用它。因此,它很自然地会向一个数组添加一个回调,然后该数组中的回调可以在未来的某个时间执行(比如当 promise 实现时)。

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

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

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

但是,这个实现在很多方面都不能正常工作。如果resolver()立即调用,则.thenCallbacks数组将为空,因为.then()尚未在 promise 上调用,然后在.then()稍后的某个时间在已解决的 promise 上调用时,它不会调用回调。

正如我在评论中所说,我不想再花时间讨论这种有缺陷的承诺实现是如何工作的。我试图回答你的直接问题,并引导你走向一个更好、更准确、更完整的 Promise 实现,你可以继续学习。这个有各种各样的问题,所以在我看来,不值得花更多时间了解它是如何工作的。

您还可以花一些时间阅读Promises/A+ 规范,这实际上并不复杂,难以阅读或理解。


推荐阅读