拒绝承诺,当不知道父var

Reject promise, when don't know parent var

本文关键字:var 不知道 承诺 拒绝      更新时间:2023-09-26

我有这个承诺,我简化了这里的代码,但我不能让它拒绝promise0。在下面的示例中,renameProfile首先读取一个包含所有配置文件信息的文件,在读取它之后,它尝试重命名它,这是没有承诺的。因此,在示例readFile是成功的,但重命名文件过程失败。但它并不排斥。

我使用Promise.jsmhttps://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);
    }
);

promise就像同步代码一样工作——你可以随意抛出错误。在你的例子中,你是返回一个错误对象,而不是抛出它。

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

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

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

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

Promise.then()返回:

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

  • 如果回调函数返回的值不是promise,包括undefined,则使用此履行值来履行新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