【问题标题】:How do promises work in JavaScript?Promise 在 JavaScript 中是如何工作的?
【发布时间】:2019-12-05 18:09:23
【问题描述】:

我刚刚实现了我的第一个函数,该函数根据 AngularJS 中的另一个承诺返回一个承诺,并且它有效。但在我决定只是这样做之前,我花了 2 个小时阅读并试图理解 Promise 背后的概念。我想如果我能写一段简单的代码来模拟 Promise 是如何工作的,那么我就能从概念上理解它,而不是在不知道它是如何工作的情况下使用它。我写不出那个代码。

那么,有人可以用原生 JavaScript 说明 Promise 是如何工作的吗?

【问题讨论】:

标签: javascript asynchronous


【解决方案1】:

promise 基本上是一个有两种方法的对象。一种方法是定义要做什么,一种方法是告诉什么时候做。必须可以按任意顺序调用这两个方法,因此对象需要跟踪调用了哪个方法:

var promise = {
  isDone: false,
  doneHandler: null,
  done: function(f) {
    if (this.isDone) {
        f();
    } else {
        this.doneHandler = f;
    }
  },
  callDone: function() {
    if (this.doneHandler != null) {
        this.doneHandler();
    } else {
        this.isDone = true;
    }
  }
};

你可以先定义动作,然后触发它:

promise.done(function(){ alert('done'); });
promise.callDone();

可以先触发动作,再定义:

promise.callDone();
promise.done(function(){ alert('done'); });

演示:http://jsfiddle.net/EvN9P/

当您在异步函数中使用 promise 时,该函数会创建空的 promise,保留对它的引用,并返回该引用。处理异步响应的代码会触发promise中的action,调用异步函数的代码会定义action。

由于其中任何一个都可以以任何顺序发生,调用异步函数的代码可以挂在 Promise 上并随时定义操作。

【讨论】:

  • 我认为这个答案可以改进。
  • 这根本不捕获what a promise is
  • @Bergi:这不是问题所在。我回答了这个问题。不是其他问题。
  • @Guffa OP 是“试图理解 Promise 背后的概念”,但我认为这个答案中的实现缺少一些关键部分
  • @Bergi:这不是 OP 所要求的。 OP 要求“一段简单的代码来模拟 Promise 的工作方式”。这就是我在答案中提出的。如果我添加了大多数 Promise 实现所包含的所有内容,它会更加复杂,也更难理解。由于 OP 不是试图理解承诺的所有方面,而是核心操作,这就是我在答案中提出的。再次,我回答了这个问题,而不是您想要提出的任何其他问题。
【解决方案2】:

为了便于理解 Javascript 中的 Promise。 你可以参考下面的例子。只需复制粘贴到一个新的 php/html 文件中并运行。

<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">

function test(n){
    alert('input:'+n);

    var promise = new Promise(function(fulfill, reject) {         
      /*put your condition here */
      if(n) {
        fulfill("Inside If! match found");
      }
      else {
        reject(Error("It broke"));
      }
    });
    promise.then(function(result) {
      alert(result); // "Inside If! match found"
    }, function(err) {
      alert(err); // Error: "It broke"
    });
}

</script>

</head>
<body>
<input type="button" onclick="test(1);" value="Test"/>

</body>
</html>
  1. 点击测试按钮,
  2. 它将创造新的承诺,
  3. 如果条件为真,则满足响应,
  4. 在调用 promise.then 之后,它会根据完成情况打印 result
  5. 如果拒绝promise.then返回错误信息。

【讨论】:

    【解决方案3】:

    promise 用法的最简单示例可能如下所示:

    var method1 = (addings = '') => {
      return new Promise(resolve => {
        console.log('method1' + addings)
        resolve(addings + '_adding1');
      });
    }
    var method2 = (addings = '') => {
      return new Promise(resolve => {
        console.log('method2' + addings)
        resolve(addings + '_adding2');
      });
    }
    
    method1().then(method2).then(method1).then(method2);
    // result:
    // method1            
    // method2_adding1    
    // method1_adding1_adding2
    // method2_adding1_adding2_adding1
    

    这是基础知识。有了它,您可以尝试拒绝:

    var method1 = (addings = '*') => {
      return new Promise((resolve, reject) => {
        console.log('method1' + addings)
        resolve(addings + '_adding1');
      });
    }
    var method2 = (addings = '*') => {
      return new Promise((resolve, reject) => {
        console.log('method2' + addings)
        reject();
      });
    }
    var errorMethod = () => {
      console.log('errorMethod')
    }
    method1()
    .then(method2, errorMethod)
    .then(method1, errorMethod)
    .then(method2, errorMethod)
    .then(method1, errorMethod)
    .then(method2, errorMethod);
    // result:
    // method1*           
    // method2*_adding1
    // errorMethod
    // method2*
    // errorMethod
    // method2*
    

    正如我们所见,如果发生故障,错误函数会被触发(始终是then 的第二个参数),然后在没有给定参数的情况下触发链中的下一个函数。

    为了高级知识,我邀请您here

    【讨论】:

      【解决方案4】:

      请检查这个简单的承诺代码。这将帮助您更好地了解 Promise 功能。

      promise 是一个对象,它可能会在未来某个时间产生单个值:要么是已解决的值,要么是它未解决的原因。 Promise 可能处于 3 种可能状态之一:已完成、已拒绝或待处理。 Promise 用户可以附加回调来处理完成的值或拒绝的原因。

      let myPromise = new Promise((resolve, reject)=>{
        if(2==2){
          resolve("resolved")
        }else{
          reject("rejected")
        }
      });
      
      myPromise.then((message)=>{
        document.write(`the promise is ${message}`)
      }).catch((message)=>{
        document.write(`the promise is ${message}`)
      })

      check this out

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-10
        • 2016-03-17
        • 2023-01-10
        • 2020-04-19
        • 2023-04-08
        • 2021-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多