对承诺的理解

时间:2016-08-25 08:42:52

标签: javascript promise

我希望使用原生deferred实施Promise并进行一些实验。

var p, _p;
p = new Promise((t, f) => {
  p.resolve = t; 
  p.reject = f;
  _p = p; // let's save it into global
});
p.then(
  console.log.bind(console, 'ok'), 
  console.log.bind(console, 'fail')
);
console.log(p === _p);      // false!
console.log(typeof p.resolve, typeof _p.resolve); // 'undefined' 'function'
_p.resolve(42); // 'ok' 42

承诺函数中指出p是什么? 为什么它是另一个实例?我该如何延长退回的?

3 个答案:

答案 0 :(得分:1)

  

承诺函数中指出了什么?

当您在承诺中设置<android.support.v7.widget.CardView xmlns:cardview="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/card_container" cardview:cardCornerRadius="2dp" cardview:cardElevation="4dp" cardview:cardUseCompatPadding="true"> <RelativeLayout android:id="@+id/relativeLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/frameLayout" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentBottom="false" android:layout_alignParentTop="true" android:layout_alignParentEnd="false" android:layout_alignParentStart="false" android:layout_above="@+id/card_description"> <LinearLayout android:id="@+id/linearView" android:layout_width="match_parent" android:layout_height="0dp" android:background="@android:color/holo_purple" android:gravity="center_vertical" android:orientation="vertical" android:visibility="gone"> <LinearLayout android:id="@+id/layoutButtons" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:orientation="vertical" android:visibility="gone"> <Button style="@style/Widget.AppCompat.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/activity_vertical_margin" android:text="@string/card_reveal_buy" /> <Button style="@style/Widget.AppCompat.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/activity_vertical_margin" android:text="@string/card_reveal_share" /> <Button style="@style/Widget.AppCompat.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/card_reveal_favorite" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/card_item_image" android:layout_width="match_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:contentDescription="@string/image" android:src="@drawable/test_image" android:scaleType="centerCrop" android:layout_gravity="center_horizontal|top" /> </FrameLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/price" android:id="@+id/card_price" android:layout_alignParentBottom="true" android:layout_alignParentStart="true" android:layout_margin="2dp" /> <TextView android:layout_width="80dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/shipping" android:id="@+id/card_shipping" android:textAlignment="viewEnd" android:layout_alignTop="@+id/card_price" android:layout_alignParentEnd="true" android:layout_marginLeft="2dp" android:layout_marginRight="2dp" android:layout_marginTop="2dp" android:layout_marginBottom="2dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="@string/desc" android:id="@+id/card_description" android:textAlignment="center" android:layout_above="@+id/card_price" android:layout_alignParentStart="true" android:layout_alignEnd="@+id/card_shipping" android:layout_marginBottom="8dp" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/card_image_description" android:id="@+id/card_shipping_icon" android:src="@drawable/ic_local_shipping" android:layout_alignTop="@+id/card_shipping" android:layout_toStartOf="@+id/card_shipping" /> </RelativeLayout> </android.support.v7.widget.CardView> 时,您将引用全局p(您声明的那个)。

p

由于您在承诺调用之前未为var p, _p; // declared, but not value set p = new Promise((t, f) => { console.log(p); //undefined console.log(window.hasOwnProperty("p")); //true window.p = 3; console.log(p); // 3 }); console.log(p); // promise 设置任何值,因此其值为p

  

为什么它是另一个实例?我该如何延长退回的?

因为在undefined设置属性时,您对promise的调用尚未完成。浏览器首先执行你发送给promise的参数(这是你的箭头函数),然后用参数调用你的promise,然后才将它的promise的返回值赋给变量p(并覆盖你对{的任何更改在你的箭头功能中{1}}。

扩展返回的Promise对象的唯一方法是在创建并分配给p之后对其进行扩展

答案 1 :(得分:0)

谢谢你们指出我的错 我最终接下来的实施:

function Deferred() {
  this.promise = new Promise((ok, fail) => {
    this.resolve = ok;
    this.reject = fail;
  });
}

!function() {
  var p = new Deferred();
  p.promise.then(
    console.log.bind(console, 'ok'), 
    console.log.bind(console, 'fail')
  );
  p.resolve(42); // ok 42
}();  

扩展Promise对象是一个坏主意。

答案 2 :(得分:0)

p确实会在您定义时拒绝并解析附加到它的函数:

p = new Promise((t, f) => {
  console.log(p) // it is not defined as a promise
  p.resolve = t; 
  p.reject = f; 
  console.log(p) // p now is defined AND has resolve and reject defined in it
  _p = p // _p now is a promise object with resolve and reject defined 
});

但是,在您完成承诺的那一刻,它将失去您添加到其中的所有额外元素。如果您因任何原因想要扩展p,可以在创建承诺后执行此操作。例如

p = new Promise((t, f) => {
  console.log(p) // it is already defined as a promise
  p.resolve = t; 
  p.reject = f; 
  console.log(p) // p now has resolve and reject defined in it too
  _p = p // _p now is a promise object with resolve and reject defined 
});
p.extraExtension = "hello"
console.log(p); // at this stage your p will have extraExtension extended to it, but its attributes and status as a Promise are also there. However, simply defining `p.resolve` and `p.reject` wouldn't make them function as proper resolve and reject methods for the promise.

Promise已经定义了resolverejecthttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject

调用它们的方法是在promise对象中简单地引用它们:

p = new Promise((t, f) => {
  console.log(p) // it is already defined as a promise
  resolve(t); // the promise will now resolve. Similarly you can call reject() here.
});

有关更多信息,请参阅此处的官方文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

您可以在那里看到Promise对象的所有固有方法和属性。