当不知道父变量时拒绝承诺

时间:2014-05-03 19:11:49

标签: javascript firefox-addon promise

我有这个承诺我在这里简化了代码,但我无法拒绝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);
    }
);

2 个答案:

答案 0 :(得分:5)

Promise就像同步代码一样工作 - 你可以随意抛出错误。在您的情况下,您返回一个Error对象,而不是抛出它。

throw new Error('renameProfile num == 2');

应拒绝承诺并触发您的错误处理。

答案 1 :(得分:1)

好吧,关于实际(重新)抛出错误的观点已经提出......但这不是唯一的错误...... doIt()将返回结果renameProfile(1),这是总是promise2 = readFile()总是成功的。

您打算做的不是返回promise2而是返回promise2.then(...),这是传播结果或promise2回调的另一个承诺。

Promise.then() returns

  

最初未决的新承诺,然后假设一个状态   取决于调用的回调函数的结果:

     
      
  • 如果回调返回的值不是承诺,包括未定义,则使用此履行值履行新承诺,   即使最初的承诺被拒绝了。
  •   
  • 如果回调引发异常,则新的承诺将被拒绝,异常作为拒绝原因,即使是原始承诺   承诺得以实现。
  •   
  • 如果回调返回一个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