繁体   English   中英

通过一个承诺来拒绝一个承诺

[英]Rejecting a Promise by passing a Promise

为什么resolve承诺正确地等待someOtherPromise完成,但是reject却没有呢? 运行以下代码示例,并检查console.log输出。 我希望“ myFailingPromise被拒绝”消息将在2000毫秒后显示,就像“ myPromise解决”一样。

 let someOtherPromise = (previousPromise) => { return new Promise((resolve, reject) => { setTimeout(() => { console.log(previousPromise + ' => someOtherPromise after 2000ms'); resolve('someOtherPromise'); }, 2000); }); } let myPromise = () => { return new Promise((resolve, reject) => { resolve(someOtherPromise('myPromise')); }); }; let myFailingPromise = () => { return new Promise((resolve, reject) => { reject(someOtherPromise('myFailingPromise')); }); }; myPromise().then((val) => { // this is executed after `someOtherPromise` resolves. console.log('myPromise resolved'); }).catch((err) => { console.log('myPromise rejected'); }); myFailingPromise().then((val) => { // this is executed after `someOtherPromise` resolves. console.log('myFailingPromise resolved'); }).catch((err) => { console.log('myFailingPromise rejected'); }); 

我知道在第二个示例中使用someOtherPromise.then(reject)可以实现预期的行为,但是我的问题是为什么不能将promise作为reject的参数,因为它可以resolve

解决承诺A时,如果解决的价值是承诺B,则您的承诺A将与承诺B的状态匹配。

但是,当您拒绝诺言时,您只给出理由,无论理由看起来像还是不像诺言都没有关系。

您需要做的是在两种情况下都通过someOtherPromise解决。

如果您要等待第一个承诺并仍然拒绝,则可以执行以下操作:

let myFailingPromise = () => {
  return new Promise((resolve, reject) => {
    someOtherPromise.then(reject);
  });
};

拒绝仅出于突出显示错误的reason 没有别的承诺。 您可以使用相同类型的另一个Promise来解决一个Promise,但只有最后一个Promise的成功案例才会出现。

看看这个改编的实现:

const someOtherPromise = new Promise((resolve, _) => {
    resolve("I am a success");
});
const failingPromise = new Promise((_, reject) => {
    reject("I failed for a reason");
});

someOtherPromise
    .then((result) => {
            console.log("some other promise resolves", result);
            failingPromise
                .then((success) => {
                    console.log("never called");
                })
                .catch((reason) => {
                    console.error("failing promise rejects", reason);
                });
        }
    )
    .catch((error) => {
        console.error("also never called", error);
    });

这是then -able方法来等待对方兑现承诺,导致回调地狱。 这就是为什么您还可以使用async / await语法的原因:

const app = async () => {
        try {
            const success1 = await someOtherPromise; // will succeed
            console.log(success1);
            const success2 = await failingPromise; // never succceds
            console.log(success2); // never be reached
        } catch (e) {
            return Promise.reject(e); // catches the error of failing promise and rethrows it, redundant but here showcases error handling
        }
    }
;

app()
    .then(() => {
        console.log("never be reached because of failing promise");
    })
    .catch(console.error);

关于带有超时的更新问题,以下是您为了始终等待另一个承诺而可以做的事情:

const otherPromise = async (willBeSuccesful: boolean) => {
    console.log("started timer for case", willBeSuccesful);

    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("resolve timer for case", willBeSuccesful);

            const successValue = "Fnord"; // whatever you want

            return willBeSuccesful
                ? resolve(successValue)
                : reject("this other promise failed because of reasons"); // only provide a reason, not another promise
        });
    };
};

const alwaysWaitForOtherPromiseThenRejectAnyway = async (otherPromise) => {
    try {
        const success = await otherPromise; // always waits 2 seconds, not matter
        console.log("other promises succeeded with value", success);
    } catch (e) {
        return Promise.reject(e); // passing through reason, redundant, only to showcase
    }

    return Promise.reject("reason why this promise failed"); // only happens after otherPromise was resolved, you could swallow that error and fail here or resolve here as well
};

const succeedingPromise = otherPromise(true);
const failingPromise = otherPromise(false);

alwaysWaitForOtherPromiseThenRejectAnyway(succeedingPromise)
    .catch((reason) => console.error(reason)); // fail after waiting for success of other promise

alwaysWaitForOtherPromiseThenRejectAnyway(failingPromise)
    .catch((reason) => console.error(reason)); // will fail as soon as otherPromise fails

在拒绝发生之前,它将始终等待超时。 拒绝将有不同的原因。 输出将是:

started timer for case true
started timer for case false
resolve timer for case true
resolve timer for case false
other promises succeeded with value Fnord
reason why this promise failed
this other promise failed because of reasons

暂无
暂无

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

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