簡體   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