繁体   English   中英

"Javascript:在承诺中解决和拒绝的目的是什么?"

[英]Javascript: In promises what is the purpose of resolve and reject?

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

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

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

最终编辑:<\/strong>我尝试使用 foo 而不是 resolve 并且它仍然有效。 怎么可能? 我根本没有定义 foo ? 除了承诺之外,我可能不了解有关 javascript 的一些东西。 我将解析更改为 foo 的代码片段<\/a>

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

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

所以当消费者使用then来检查 promise 的输出时。 由 resolve 返回的任何内容都会提供给消费者。

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

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 来运行上述示例,并亲自查看输出是什么。

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

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

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

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

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

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

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

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

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

例如:

想象在以下示例中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)

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

  1. 待办的
  2. 解决
  3. 拒绝了

当一个promise被解析时,在then()方法中传递的回调被调用。 如果承诺被拒绝,则调用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))

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

  • 当承诺被拒绝时,调用catch方法中传递的回调
  • 当承诺被解决时,调用then方法中传递的回调

我花了很多时间试图弄清楚这一点。 不幸的是,对于任何精通 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()。

解决

拒绝


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

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

<Promise 代码将从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); });

resolvereject本质上都做相同的事情。 它们是回调。 但是,它们将有助于处理错误或您需要运行以确定合格/不合格的任何其他逻辑。

示例:拒绝最终将落入您的陷阱。 解决最终于您的(解决)

 function myPromise(rejectOrResolve) { return new Promise( (resolve, reject) => { if (rejectOrResolve) { resolve(); } else { reject(); } }); } // Resolved (Success) myPromise(true).then( t => { console.log('resolve'); }).catch( e => { console.log('reject'); }); // Rejected (Error) myPromise(false).then( t => { console.log('resolve'); }).catch( e => { console.log('reject'); }); 

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM