我有这个承诺我在这里简化了代码,但我无法拒绝promise0
。在下面的示例中,renameProfile
首先读取包含所有配置文件信息的文件,然后在读取之后,它会尝试重命名它,这是在没有承诺的情况下完成的。因此,在示例readFile
中成功但重命名文件过程失败。但它并没有拒绝。
我正在使用Promise.jsm https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm
function doit() {
var promise1 = renameProfile(1);
promise1.then(
function () {
console.log('promise1 success');
},
function onReject(rsn) {
console.log('promise1 failed rsn = ' + rsn);
}
);
return promise1;
}
function renameProfile(readFileFirst) {
if (readFileFirst == 1) {
console.log('doing read file first');
var promise2 = readFile();
promise2.then(
function () {
console.log('promise2 success - read file success will now rename the profile');
return renameProfile(0);
},
function (rsn) {
console.log('promise2 failed - read file failed rsn = ' + rsn);
return new Error('read file failed rsn = ' + rsn);
}
);
return promise2;
} else if (readFileFirst == 0) {
//always reject promise
console.log('doing renameProfile');
return new Error('renameProfile failed');;
}
}
function readFile() {
let deferred = Promise.defer();
deferred.resolve('successfully read file');
return deferred.promise;
}
var promise0 = doit();
promise0.then(
function () {
console.log('promise0 success');
},
function (rsn) {
console.log('promise0 failed rsn = ' + rsn);
}
);
答案 0 :(得分:5)
Promise就像同步代码一样工作 - 你可以随意抛出错误。在您的情况下,您返回一个Error对象,而不是抛出它。
throw new Error('renameProfile num == 2');
应拒绝承诺并触发您的错误处理。
答案 1 :(得分:1)
好吧,关于实际(重新)抛出错误的观点已经提出......但这不是唯一的错误...... doIt()
将返回结果renameProfile(1)
,这是总是promise2 = readFile()
总是成功的。
您打算做的不是返回promise2
而是返回promise2.then(...)
,这是传播结果或promise2
回调的另一个承诺。
最初未决的新承诺,然后假设一个状态 取决于调用的回调函数的结果:
- 如果回调返回的值不是承诺,包括未定义,则使用此履行值履行新承诺, 即使最初的承诺被拒绝了。
- 如果回调引发异常,则新的承诺将被拒绝,异常作为拒绝原因,即使是原始承诺 承诺得以实现。
- 如果回调返回一个promise,新的promise将最终采用与返回的promise相同的状态。
以下是我如何更正代码:
function doit() {
var promise1 = renameProfile(1);
promise1.then(
function () {
console.log('promise1 success');
},
function onReject(rsn) {
console.log('promise1 failed rsn = ' + rsn);
}
);
return promise1;
}
function renameProfile(readFileFirst) {
if (readFileFirst == 1) {
console.log('doing read file first');
var promise2 = readFile();
// !!! return the right thing.
return promise2.then(
function () {
console.log('promise2 success - read file success will now rename the profile');
return renameProfile(0);
},
function (rsn) {
console.log('promise2 failed - read file failed rsn = ' + rsn);
throw new Error('read file failed rsn = ' + rsn);
}
);
} else if (readFileFirst == 0) {
//always reject promise
console.log('doing renameProfile');
throw new Error('renameProfile failed');
}
}
function readFile() {
let deferred = Promise.defer();
deferred.resolve('successfully read file');
return deferred.promise;
}
var promise0 = doit();
promise0.then(
function () {
console.log('promise0 success');
},
function (rsn) {
console.log('promise0 failed rsn = ' + rsn);
}
);
(promise1.then()
仅用于记录,对结果没有影响。)
导致
"doing read file first" Scratchpad/1:16
"promise2 success - read file success will now rename the profile" Scratchpad/1:20
"doing renameProfile" Scratchpad/1:30
"promise1 failed rsn = Error: renameProfile failed" Scratchpad/1:8
"promise0 failed rsn = Error: renameProfile failed" Scratchpad/1:47