Javascript 对象分解承诺中的解析和拒绝
对象分解不是我最喜欢的,我经常试图避免使用它。然而,在这种特殊情况下,我太好奇了,不能忽视正在发生的事情 现在我们可以这样做了Javascript 对象分解承诺中的解析和拒绝,javascript,promise,destructuring,Javascript,Promise,Destructuring,对象分解不是我最喜欢的,我经常试图避免使用它。然而,在这种特殊情况下,我太好奇了,不能忽视正在发生的事情 现在我们可以这样做了 var o = {}, x = 1, y = 2; o = {x,y}; console.log(o); // <- {x: 1, y: 2} 我有一种奇怪的感觉,好像我遗漏了一些非常基本的东西,但我不知道是什么。您所展示的任何代码中都没有解构 您正在将o重新指定给一个简单的普通新对象,该对象具有两个属性: o = {resolve,reject
var o = {},
x = 1,
y = 2;
o = {x,y};
console.log(o); // <- {x: 1, y: 2}
我有一种奇怪的感觉,好像我遗漏了一些非常基本的东西,但我不知道是什么。您所展示的任何代码中都没有解构 您正在将
o
重新指定给一个简单的普通新对象,该对象具有两个属性:
o = {resolve,reject}
这只是ES2015引入的,与
o = {resolve: resolve, reject: reject}
当然,前面的promise
属性随后会丢失,因为它存在于一个不再被o
引用的对象上(如果内存中没有其他对它的引用,它最终将被垃圾收集)
试一试
o.promise=newpromise((解析,拒绝)=>o={…o,解析,拒绝})代码>
不,…o
也不是解构,而是解构
你也可以使用
o.promise = new Promise((resolve,reject) => o = Object.assign(o, { resolve, reject }));
请注意,Object.assign()
会触发setter(如果有的话),而spread语法不会。问题
让我用这个方便的图表来解释发生了什么:
var p = function(o){
// 1 2 3
// v vvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
o.promise = new Promise((resolve,reject) => o = {resolve,reject});
// ^ ^ ^^^^^^^^^^^^^^^
// 6 5 4
console.log(o)
return o;
}({});
console.log(p);
对o.promise
的分配开始引擎将首先引用o
,,然后评估分配给promise
属性的内容
赋值表达式是使用new
调用Promise
构造函数。引擎在将任何内容分配给promise
属性之前,必须评估整个内容并获取一个对象
Promise
构造函数接收执行器函数。该函数立即被调用。在执行人完成之前,承诺建设无法完成
对于整个图片来说无关紧要,但为了清晰起见,添加了一个对象-创建对象时有两个属性resolve
和reject
对象被分配到o
。请注意,步骤1。这是作业的开始。作业还没有完成。在中途在分配给o.promise
完成之前,代码重新分配o
。但是,这是在引擎引用分配给o
的初始对象后发生的。现在有两个对象与o
相关:
- 步骤1开始时分配的一个。发生了
- 现在分配给它的一个-在步骤5之后
(为简洁起见压缩内容):执行器功能已完成。Promise
构造函数也已完成。完整表达式newpromise((resolve,reject)=>o={resolve,reject})
已计算并生成一个值。promise
属性的赋值现在可以继续。因为它使用步骤1中的引用代码指定给不再指定给o
的对象的承诺值
(图中未显示)在步骤1中分配给o
的初始对象。没有更多的参考资料。它不符合垃圾收集的条件,将从内存中消失。(最初分配的)o
无效,长寿(新分配的)o
整个情况可以简化并用以下代码表示:
//获取对同一对象的两个引用
设o1={};
设o2=o1;
承诺=(()=>o1={解决:“foo”,拒绝:“bar})();
控制台日志(o1);
控制台日志(o2)代码>我在这里找不到任何解构。@RandyCasburn与解构无关,这只是对象文字速记语法。与@Redu相比,它们是不可接受的。对象文字中的扩展语法不同于扩展数组。。我试图解释两者之间的区别。同样值得注意的是,这一承诺只是一条红鲱鱼。没有任何异步事件发生-给予承诺构造函数的执行器只是立即执行。它基本上相当于一个IIFE。@VLAZ我刚刚验证了@Redu的最后一条评论是正确的。你知道为什么散布会导致{reject:f(),resolve:f()}
而Object.assign会导致{promise,reject:f(),resolve:f()}
吗?@conneso执行o={}
时,它会丢弃旧对象并创建一个新对象。拥有o={…o}
并没有真正的帮助,因为o
上没有属性。这与o={}
相同,它创建了一个新对象,并切断了对旧对象的引用,使其符合GC条件。这发生在o.promise
赋值之前-在那里o
仍然引用旧对象(就在它成为GC提要之前)。没有promise
属性可扩展到新创建的对象中,因为它尚未指定。所以,它仍然是“当承诺解决时。”承诺没有解决。正如我所说的,整个承诺是一个骗局。如果你给构造函数一些函数,它就会立即执行。生命中唯一的区别是1。返回值为2。将使用两个特定参数调用该函数。这两项都与实际执行无关:newpromise(fn)
将在函数内容解析时与fn()的作用相同。马上就到。而且,resolve
从未被调用,承诺正在等待中。@Redu并不特别。这只是一条线上的大量操作。你需要从右到左阅读它们,因为这是分辨率的顺序。但是写得更让人困惑。我最后做了类似于o.promise=newpromise((…rs)=>[o.resolve,o.reject]=rs)
的事情,就像你在上一段代码中建议的那样。@Redu修改了答案,使用rs
。我写的时候不喜欢args
,但我不擅长命名东西,所以找不到更好的。
o.promise = new Promise((resolve,reject) => o = Object.assign(o, { resolve, reject }));
var p = function(o){
// 1 2 3
// v vvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
o.promise = new Promise((resolve,reject) => o = {resolve,reject});
// ^ ^ ^^^^^^^^^^^^^^^
// 6 5 4
console.log(o)
return o;
}({});
console.log(p);