为什么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)
可以实现预期的行为,但我的问题是为什么承诺作为reject
的参数是不可能的,因为它适用于{{1 }}
答案 0 :(得分:3)
当您解决承诺A时,如果您解决它的值是承诺B,那么您的承诺A将与承诺B的状态相匹配。
然而,当你拒绝一个承诺时,你唯一的理由是,无论理由是否与承诺无关。
您需要做的是在两种情况下都使用someOtherPromise
来解决。
如果你想等待第一个承诺并拒绝,你可以这样做:
let myFailingPromise = () => {
return new Promise((resolve, reject) => {
someOtherPromise.then(reject);
});
};
答案 1 :(得分:1)
拒绝仅接受reason
以突出显示错误。不是另一个承诺。您可以使用相同类型的另一个承诺解决承诺,但只能看到您将看到的最后承诺的成功案例。
看看这个改编的实施:
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
- 等待其他承诺导致回调地狱的方法。这就是为什么你也可以使用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);
答案 2 :(得分:0)
关于超时的更新问题,以下是您可以做的事情,以便始终等待另一个承诺:
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