Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 调用then函数时如何触发回调?_Javascript_Promise - Fatal编程技术网

Javascript 调用then函数时如何触发回调?

Javascript 调用then函数时如何触发回调?,javascript,promise,Javascript,Promise,我发现了一个定制的js promise实现,并试图理解它,但我无法理解如何执行或触发回调,因为promise的定义是立即调用的,但我们只是在实现中推进回调数组 有人能澄清这一点吗首先,这是对承诺的一种特别糟糕的执行,因为它做了各种各样的错事: 它不会在当前执行线程完成后异步解析,这可能会导致不一致的计时问题 它不支持正确链接.then().then()其中.then()返回一个新的承诺,因此第二个.then()仅在解决第一个承诺后调用其处理程序 它不支持正确的链接,.then()回调处理程序可

我发现了一个定制的js promise实现,并试图理解它,但我无法理解如何执行或触发回调,因为promise的定义是立即调用的,但我们只是在实现中推进回调数组


有人能澄清这一点吗首先,这是对承诺的一种特别糟糕的执行,因为它做了各种各样的错事:

  • 它不会在当前执行线程完成后异步解析,这可能会导致不一致的计时问题
  • 它不支持正确链接
    .then().then()
    其中
    .then()
    返回一个新的承诺,因此第二个
    .then()
    仅在解决第一个承诺后调用其处理程序
  • 它不支持正确的链接,
    .then()
    回调处理程序可以返回将插入到链中的承诺
  • 它不会调用承诺解析后添加的
    .then()
    处理程序
  • 它没有锁定承诺的状态,因此无法更改
  • 它不会捕获executor或
    .then()
    .catch()
    处理程序中的同步异常,并将它们转换为被拒绝的承诺
  • 为了更好的实现,我建议您参考以下代码:这段代码显然是这样开始的,因为这将让您更好地了解实现承诺所涉及的内容

    当promise的定义被立即调用时,我无法理解回调是如何执行或触发的,但我们只是在随后的实现中推进回调数组

    .then()
    所做的是注册一个回调(保存它),以便在将来某个时候调用它。因此,很自然,它只需向数组中添加一个回调,然后该数组中的回调就可以在将来某个时候执行(比如当承诺兑现时)

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

    .then()
    回调随后存储在一个数组中

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

    但是,这种实现在很多方面都不能正常工作。如果立即调用
    resolver()
    ,那么
    .thenCallbacks
    数组将为空,因为
    .then()
    尚未对承诺进行调用,然后当稍后对已解析的承诺调用
    .then()
    时,它永远不会调用回调

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


    您还可以花一些时间阅读,阅读或理解起来并不复杂。

    我不理解您的要求,但此promise实现不符合规范,因为它在解决promise时立即调用
    。然后()
    处理程序,而不是在事件循环的下一个刻度上。它也不处理承诺链接(当
    .then()
    处理程序返回另一个承诺时)。是的,我知道根据规范,这不是完美的实现,但我想了解我们只是将回调推到thenarray中,但它们是如何及时执行或触发的,您仍然可以在此实现中链接then。请检查playcode链接All
    。然后()
    应该做的是注册稍后可以调用的回调(当承诺被解决或拒绝时)。还是不明白你在问什么。在这种情况下,“注册”意味着将它们放入一个数组中以保存它们以供以后使用。此实现还存在许多其他问题,因为它也没有调用
    .then()
    处理程序,因为它是在承诺已经解决之后添加的。我不是说链接
    .then().then()
    。我说的是从
    .then()
    处理程序返回一个新的承诺,该处理程序应该将该新承诺插入到链中,但这不起作用。基本上,这是大约20%的实现。
    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));