为什么我的第二个 javascript 承诺调用 return 与第一个相同的值?

Why does my 2nd javascript promise call return the same value as the 1st?

大家好,我是 javascript 的新手,最近一直在学习 promises。在继续我的逻辑之前,我试图等待网络调用的结果。为此,我认为我需要一个等待网络调用结果的承诺。我一直在练习 promises 并注意到一些我不理解的行为。

var mybool = false;

// Promise
var mypromise = new Promise(
    function (resolve, reject) {
        if (mybool) {
            var pvalue = 'PASS';
            resolve(pvalue);
        } else {
            var fvalue = new Error('FAIL');
            reject(fvalue);
        }
    }
);


// call promise
var callpromise = function () {
    mypromise
        .then(function (fulfilled) {
            // yay, you got a new phone
            console.log(fulfilled);
        })
        .catch(function (error) {
            // ops, mom don't buy it
            console.log(error.message);
        });
}

callpromise();
console.log('This will appear first since prev function call is still thinking');
mybool = true;
console.log(mybool);
callpromise();

正如您所见,var mybool 决定了 promise 函数的输出。当我 运行 这个程序时,这是输出:

"This will appear first since prev function call is still thinking"
true
"FAIL"
"FAIL"

有人可以解释为什么即使在翻转 mybool var 之后,第二个 callpromise() 仍然输出一个我只期望来自 mybool = false 的值吗?

承诺不会得到 "called",它们会被创建。在实际调用 callpromise 之前,您创建了一次 mypromise。到那时,mybool 为假。如果您想在代码中的特定点创建 Promise,或者如果您想要多个 Promise,请在函数内部创建 Promise。

你指定作为then函数的第一个参数的函数("callback"或"handler"是经常被调用的函数,将在promise [=74=时被调用],that 函数("callback",而不是 then)的参数是 you 自己提供的值resolve 调用的参数。

意味着在您的示例中,fulfilled"PASS"(您指定为 resolve 的参数的 pvalue 的值)。名称 fulfilled 在这里似乎不是一个好的候选者,可能是由于您(错误地)理解 promises 工作的方式。一个合适的名称是 value,或 pvalue(与 resolve 承诺相同)。

但是你遗漏的关键难题是每次你用一些回调函数调用 then 时,如果承诺是,回调函数 执行在 "resolved" 状态(意味着 resolve 之前已经被调用)。

因此您可以调用 then 1000 次,您的回调将被调用 1000 次,并且具有相同的解析值("promised")值。

让我们分解一下你的例子:

  1. 在执行 var mypromise = ...; 语句时,mypromise promise 已创建 并且 已解决 - Promise 构造函数立即调用提供的函数(在承诺术语中称为 "executor" ),并且在您的情况下,此执行程序函数立即调用 resolve ,这将承诺置于 "resolved" 状态。

  2. callpromise 只是一个函数,当执行时,它本质上会导致用户代理调用作为参数提供给 then 的函数,只要 mypromise 承诺处于 "resolved" 状态,它已经是(见 1.)

  3. 你调用了两次 callpromise,但承诺在第一次调用之前就已经解决了,所以 mybool 的值对承诺的价值 - 承诺已经解决了一次,仅此而已。

尝试在 promise 执行器函数(评估 mybool 的函数)中添加一个 console.log 调用并观察你的 promise 是如何解决的 once,然后你甚至创建了 callback 函数。

对您所做的事情最简单的更改可能是将 mybool 传递给您的 promise-creator,正如其他人指出的那样应该是一个函数。

我还添加了一个计数器,这样您就可以看到 resolve/reject 与创建顺序不同的结果。

var mypromise = function(mybool, counter) {
    return new Promise(
        function (resolve, reject) {
            if (mybool) {
                var pvalue = 'PASS-' + counter;
                resolve(pvalue);
            } else {
                var fvalue = new Error('FAIL-' + counter);
                reject(fvalue);
            }
        }
    )
}


// call promise
var callpromise = function (mybool, counter) {
    mypromise(mybool, counter)
        .then(function (fulfilled) {
            // yay, you got a new phone
            console.log(fulfilled);
        })
        .catch(function (error) {
            // ops, mom don't buy it
            console.log(error.message);
        });
}


callpromise(false, 1);
console.log('This will appear first since prev function call is still thinking');
callpromise(true, 2);