【问题标题】:Javascript: In promises what is the purpose of resolve and reject?Javascript:在承诺中解决和拒绝的目的是什么?
【发布时间】:2022-02-05 01:18:00
【问题描述】:

据我了解,resolve 和 reject 在提供给 promise 构造函数的回调中指定,并在回调中调用。但是解决和拒绝(我认为)总是做同样的事情,那么为什么还要指定它们呢?

编辑:我应该澄清一下:我不认为解决与拒绝做同样的事情;我的意思是 resolve 似乎总是 resolve 而 reject 总是拒绝——有没有办法传递一个函数而不是 resolve 做其他事情?

编辑:为了进一步澄清,正如我在下面的评论中所做的那样:如果 Promise 构造函数采用一个函数,该函数又接受 resolve 和 reject,并且这些总是要在函数中调用,为什么必须将 resolve 和 reject 指定为参数有吗?

最终编辑:我尝试使用 foo 而不是 resolve,但它仍然有效。这个怎么可能?我根本没有定义 foo ?除了承诺之外,我可能不了解有关 javascript 的某些内容。 code snippet where i changed resolve to foo

【问题讨论】:

  • 他们不做同样的事情。是什么让你产生了这个想法?
  • “总是做同样的事情”是什么意思?你觉得他们做什么?如果没有resolve 可用,您将如何解决 Promise?
  • 如果不指定,当promise完成或者有错误的时候怎么调用?
  • reject(…) 可以被resolve(Promise.reject(…)) 取代,当然,但他们不做同样的事情吗?即使您只需要一个 - 为什么您认为不需要指定一个?
  • “指定”是指“声明为参数”吗?

标签: javascript promise


【解决方案1】:

当你创建一个 JS Promise 时,你期望一些任务异步发生。此任务可能成功或失败。成功和失败是根据任务是什么来定义的。

当你创建一个新的 Promise 时,你作为创建者必须指定当任务成功或失败时要做什么。将相同的内容传达给承诺解决/拒绝的消费者会派上用场。

所以当消费者使用then 来检查承诺的输出时。解析返回的内容将提供给消费者。

当消费者使用catch 来检查承诺的输出时。拒绝返回的任何东西都会交给消费者。

import {Promise} from 'es6-promise'


const foo = true;
const bar = new Promise((resolve, reject) => {
    if (foo) {
        resolve(4);
    } else {
        reject(2);
    }
})
bar.then((value) => console.log(value)).catch((value) => console.log(value));

您可以通过将 foo 的值更改为 true/false 来运行上述示例,并亲自查看输出是什么。

【讨论】:

    【解决方案2】:

    我假设您指的是 then() 函数,它接受两个回调,一个在 promise 被解决时,一个在它被解决时。该模式通常如下所示:

    myPromise.then(result => {
            // do something here
        },
        error => {
        }
    );
    

    如果承诺得到解决,一切都按预期进行,第一个回调应该正常进行。如果 promise 被拒绝,第二个回调应该执行错误处理,可能会向用户显示适当的消息。它们从不做同样的事情。

    如果您有应该始终发生的逻辑,无论是否有错误,您都应该将另一个调用链接到then()

    myPromise.then(result => {
            // do something here
        },
        error => {
            // do something here
        }
    ).then(result => {
            // do something here
        }
    );
    

    这在概念上与许多编程语言中的try...catch...finally 相同。

    【讨论】:

      【解决方案3】:

      解决和拒绝不要“做同样的事情”。

      当你解决一个承诺时,你是在说“这是这个承诺的成功响应”。

      当你拒绝一个承诺时,你是在说“这个承诺失败了,因为......”。

      例如:

      想象一下,在以下示例中,accountApiRequest() 实际上执行了一个 API 请求来获取一个帐户。如果没有帐户,它很可能会返回null 或抛出异常。

      当一个承诺成功时,你会resolve它。当一个承诺不成功时,它将是rejected

      成功的承诺

      function accountApiRequest() {
          return {
              id: 1234,
              username: 'Jim',
          }
      }
      
      function getAccount() {
          return new Promise(function(resolve, reject) {
              account = accountApiRequest()
              if (!account) {
                  return reject('Unable to fetch account')
              }
              return resolve(account)
          });
      }
      
      getAccount().then(console.log).catch(console.log)

      承诺失败

      function accountApiRequest() {
          return null
      }
      
      function getAccount() {
          return new Promise(function(resolve, reject) {
              account = accountApiRequest()
              if (!account) {
                  return reject('Unable to fetch account')
              }
              return resolve(account)
          });
      }
      
      getAccount().then(console.log).catch(console.log)

      【讨论】:

      • 我的问题是,resolve 的隐含类型在哪里确定?我的意思是,在 Java 中,resolve 参数将是一个类型/类。 resolve 的行为是如何确定的?
      • 我不确定我是否理解您的问题。 resolve 只是一个回调函数,更具体地说你可以想象在这种情况下resolveconsole.log。您可以随意调用它们,但Promise 构造函数中的参数顺序决定了它们的用途。
      【解决方案4】:

      在 Promise 构造函数中,我们有一个回调函数,它以 resolvereject 方法作为参数。使用构造函数创建 Promise 后,Promise 可以具有三种状态:

      1. 待处理
      2. 已解决
      3. 拒绝

      当一个 promise 被解决时,在 then() 方法中传递的回调就会被调用。如果 promise 被拒绝,则调用在 catch() 方法中传递的回调。例如:

      const prom = new Promise((resolve, reject) => {
        
        setTimeout(() => {
          if(Math.random() > 0.5) {
            resolve('resolved');
          } else {
            reject('rejected');
          }
        }
        , 2000)
        
      });
      
      prom.then((val) => console.log('succes: ' + val))
          .catch((val) => console.log('fail: ' + val))

      在我们的示例中,resolve 或 reject 在 setTimeout 中调用,因此承诺的状态是前 2 秒 pending。在setTimeout 过期后,Promise 会根据Math.random() 的值被解决或拒绝。然后执行thencatch 回调来处理promise 的结果。

      • 当 promise 被拒绝时,在 catch 方法中传递的回调被调用
      • 当 Promise 被解析时,在 then 方法中传递的回调被调用

      【讨论】:

      • 如果不是“Promise((resolve, reject) =>...”,我们可以说“Promise((foo,bar)=>...”并定义 foo 和 bar 函数吗?如果不是,如果必须始终使用 resolve 和 reject 并且它们始终具有相同的功能,那为什么还要指定它们呢?
      • 名称无关紧要,您可以使用 Promise((foo,bar)=>.. 就像您说的那样。在 promise 构造函数中,这些只是作为参数公开的函数,在Promise 构造函数。这正是这个 API 的工作方式。
      • new Promise 总是接受一个函数并公开 2 个参数 (res, rej),它们是函数,你不必使用它们,但你可以。这些名称是任意的,但它们可以让您根据自己的预定义条件轻松解决或拒绝承诺。
      • 如果我确实使用了 foo 和 bar,是否必须定义这些函数?当我在节点提示符下输入“resolve”或“Resolve()”或“Resolve”时,我会返回“未定义”,这让我很惊讶——我原以为 Resolve 是一个像 Promise 一样的内置函数。我认为这就是我困惑的本质。
      • 如果我使用“foo”作为“解决”承诺的第一个参数,“foo”会被理解为可以解决的东西还是必须预先定义?如果是这样,“解决”在哪里定义?
      【解决方案5】:

      当我阅读 Promises 时,我也有同样的问题。而且我了解到您不需要自己定义解析和拒绝函数(它们将被忽略,并且无论如何都会调用标准的解析/拒绝函数):我认为它们是特殊函数,可让您指示是否解析或通过调用其中一个来拒绝承诺;以及通过将参数传递给这些函数在每种情况下返回什么值。在 promise 构造函数中如何命名它们并不重要——第一个参数是解析函数,第二个参数是拒绝。

      【讨论】:

        【解决方案6】:

        我花了很多时间试图弄清楚这一点。不幸的是,对于任何精通 JS 语法的人来说,都不会真正理解这个问题......

        对我来说,在解开简洁的 JS 语法糖之后就很清楚了:

        function promise_executor(resolve_callback_provided_by_promise_instance, reject_callback_provided_by_promise_instance) {
            if (<some_condition>) {
                // success
                var response='bla';
                resolve_callback_provided_by_promise_instance(response);
            } else {
                // fail
                var error=new Error('failed');
                reject_callback_provided_by_promise_instance(error);
            }
        }
        
        var promise_instance = new Promise(promise_executor);
        

        所以rejectresolve 只是promise 实例将调用的回调的随机名称。

        它们有适当的接口,就像两者都需要 1 个对象类型的参数。该参数将被传递给 Promise.then() 或 Promise.catch()。

        resolve

        reject


        然后,当你使用它们时,它是这样的:

        function success_callback(param_from_resolve) {
            console.log('success() ', param_from_resolve);
        }
        
        function fail_callback(param_from_reject) {
            console.log('fail(): ', param_from_reject);
        }
        
        promise_instance
        .then(success_callback)   // this will be the var 'resolve' from above
        .catch(fail_callback);    // this will be the var 'error' from above
        

        整个代码流程是这样的:

        promise_executor() 代码会使用 2 个函数作为参数调用>

        // obviously, the promise_executor() function has its own name in the Promise object
        promise_executor(Promise.reject, Promise.resolve);
        

        promise_executor() 将-希望-调用resolve或reject回调,这将反过来触发then()catch()的回调>

        then()>

        resolve_callback_provided_by_promise_instance(response) 获取response 参数并将其提供给来自then() 的回调>

        param_from_resolve(response)
        

        它会像这样下降(这不是实际发生的事情,因为实际上,微队列、事件循环等都参与其中——这是正在发生的事情的要点的线性化版本):

        你所看到的:

        var promise = new Promise(promise_executor);
        

        执行的内容:

        function Promise.constructor(exec_callback_fnc) {
            var this = object();
            this.exec_callback_fnc = exec_callback_fnc; // this is "promise_executor"
            return this;
        }
        

        你所看到的:

        // at some point in "this.exec_callback_fnc":
        resolve_callback_provided_by_promise_instance(response)
        

        执行的内容:

        function promise_instance.resolve(param) {
            this.param_from_resolve = param;
            promise_instance.resolved = true;
        }
        

        你所看到的:

        promise_instance
        .then(success_callback)
        

        执行的内容:

        promise_instance.exec_callback_fnc(promise_instance.resolve, promise_instance.reject);
        
        if (promise_instance.resolved) {
        
            function promise_instance.then(callback_fnc) {
                callback_fnc(this.param_from_resolve);  // this is "success_callback"
            }
        }
        

        最后,让我们看看,语法如何让整个事情变得更简洁:

        function promise_executor(resolve_callback_provided_by_promise_instance,
                                  reject_callback_provided_by_promise_instance) {
            if (<some_condition>) {
                // success
                var response='bla';
                resolve_callback_provided_by_promise_instance(response);
            } else {
                // fail
                var error=new Error('failed');
                reject_callback_provided_by_promise_instance(error);
            }
        }
        
        var promise_instance = new Promise(promise_executor);
        
        function success_callback(param_from_resolve) {
            console.log('success() ', param_from_resolve);
        }
        
        function fail_callback(param_from_reject) {
            console.log('fail(): ', param_from_reject);
        }
        
        promise_instance
        .then(success_callback)
        .catch(fail_callback);
        

        会变成:

        new Promise((resolve_callback_provided_by_promise_instance,
                     reject_callback_provided_by_promise_instance) => {
            if (<some_condition>) {
                // success
                var response='bla';
                resolve_callback_provided_by_promise_instance(response);
            } else {
                // fail
                var error=new Error('failed');
                reject_callback_provided_by_promise_instance(error);
            }})
        // "response" -> "param_from_resolve"
        .then((param_from_resolve) => { console.log('success() ', param_from_resolve); })
         // "error" -> "param_from_reject"
        .catch((param_from_reject) => { console.log('fail(): ', param_from_reject); });
        

        【讨论】:

          猜你喜欢
          • 2019-08-06
          • 2023-03-26
          • 1970-01-01
          • 2016-10-20
          • 2013-06-22
          • 1970-01-01
          • 2020-03-07
          • 2016-01-16
          • 1970-01-01
          相关资源
          最近更新 更多