有人可以解释以下代码是如何工作的吗?
var a = () => {
return Promise.resolve('aaa');
};
var b = () => {
return Promise.resolve('bbb');
};
a()
.then(() => { b() })
.then(console.log); // logs undefined
a()
.then(b())
.then(console.log); // logs aaa
a()
.then(b)
.then(console.log); // logs bbb
我想知道单个承诺上多个.then的执行顺序以及b()vs b vs promise()=> {b()}使输出产生差异。
答案 0 :(得分:2)
Secnario A:您的第一个人没有从.then()
处理程序返回任何内容(return
内的{}
语句中没有{}
语句}和箭头函数在.then()
}时不使用隐式返回,因此undefined
处理程序的返回值为.then(() => { b() })
,这是什么你记录。
.then(() => { return b() }) // since there are {}, you must have an actual `return`
.then(() => b()) // use implicit return in arrow function
.then(b) // just pass function reference directly
需要这些才能正常运作:
b()
方案B:第二个提前调用b()
并将返回值从.then()
传递给您的.then()
处理程序。 .then(b())
处理程序期望将函数引用传递给它们,而不是承诺,因此它们不会使用您传递给它们的promise(它们会忽略它,因为它不是函数引用)。请注意,b()
将首先执行.then()
,然后将其返回值传递给.then()
。这显然不是你想要的,也不是b
的设计用途。有关详细说明,请参阅下面的承诺规范详细信息。
场景C:第三个正确地将指向.then()
的函数引用传递给.then()
处理程序,因此它是唯一一个正确链接两个promise的人。 / p>
方案B的承诺规范说明
在第二种情况下,您将承诺传递给.then(somePromise)
处理程序,如.then()
。 promise规范非常清楚地说明aaa
必须传递一些可调用的东西(这意味着一个函数引用)。当你没有传递一个函数引用时,你传递的任何内容都将被忽略,之前解析的值(在你的情况下为.then()
)将被传递到链中。以下是承诺规范如何涵盖:
在25.4.5.3中,有PerformPromiseThen()
的规范。
最终会调用onFulFilled
,这是下一个section 25.4.5.3.1
该部分解释了如果aaa
参数不可调用(例如不是函数引用),那么"识别"被替代。
在文档中进一步展望,"身份"在section 25.4.1.2
中定义应该应用于传入值的函数,其返回值将控制派生的promise所发生的情况。如果[[Handler]]是" Identity"它相当于一个只返回第一个参数的函数。
这意味着忽略了作为onFulFilled参数传递的任何内容以及一个身份函数(返回传递给它的任何第一个参数的函数)。在您的情况下,第一个参数是您的第一个承诺的解析值SELECT CASE WHEN cumulative_customers < 5
OR cumulative_customers = 5 AND customer >= 1
THEN cumulative_customers END AS cumulative_customers
, ... -- more columns
FROM (
SELECT ... -- your current query here
) sub;
,这就是为什么您在第二个方案的日志中看到的内容。