簡體   English   中英

我如何推遲 ES6 promise,如 jquery Deferred?

[英]How do I defer an ES6 promise like jquery Deferred?

1.使用es6 promise,但語法不正確。

我正在使用 es6,並想制作一個延遲確認對話框:

// First, create an empty promise:
let promise = new Promise((resolve, reject) => {})

// Then, show the dialog:
let $dialog = $('#dialog-confirm').show();

// FAIL: I want to trigger the promise resolver, but failed.
$dialog.find('.btn-yes').click(() => { promise.resolve(); })
$dialog.find('.btn-no').click(() => { promise.reject(); })

當我點擊按鈕時,它失敗了,因為 promise 沒有rejectresolve方法。

未捕獲的類型錯誤:promise.resolve 不是函數(...)

2. jQuery工作代碼:

如果使用 jQuery,我們可以執行以下操作:

// First, create an empty promise:
var dfd = $.Deferred();
var promise = dfd.promise();

// Then, show the dialog:
var $dialog = $('#dialog-confirm').show();

// SUCCESS: jQuery deferred works
$dialog.find('.btn-yes').click(() => { dfd.resolve(); })
$dialog.find('.btn-no').click(() => { dfd.reject(); })

3. 盡量找一個es6的deferred interface。

所以我搜索了 deferred 的ES6 EDITION

https://github.com/seangenabe/es6-deferred

但我仍然得到一個錯誤:

undefined:1 未捕獲(承諾)Object {}

實際上,代碼只是保持內部resolve並使用閉包將 function reject到外部:

https://github.com/seangenabe/es6-deferred/blob/master/deferred.js

如果我這樣做,同樣的策略:

let dfd = {};

let $dialog = $('#dialog-confirm').show();

let promise = (function() {
    return dfd.promise = new Promise(function(resolve, reject) {
        dfd.resolve = resolve;
        dfd.reject = reject;
    });
})();

// FAIL: still not working.
$dialog.find('.btn-yes').click(() => { dfd.resolve(); })
$dialog.find('.btn-no').click(() => { dfd.reject(); })

那么,如何從我的 promise 創建調用中提取resolvereject操作?

對於那些從 Google 來到這里的人,值得一提的是 ES6 承諾很好,我經常使用它們。 但是,在某些用例中,延遲模式會顯着減少代碼。 在大多數情況下,您可能應該只使用 ES6 承諾,但在那些延遲模式有意義的特殊情況下,它很容易包裝 ES6 承諾。 在我看來,包含一個節點模塊似乎有點過頭了。

function generateDeferredPromise() {
  return (() => {
    let resolve;
    let reject;

    let p = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
    });

    return {
      promise: p,
      reject,
      resolve
    };
  })();
}

在promise中移動jquery語句

let promise = new Promise((resolve, reject) => {
 let $dialog = $('#dialog-confirm').show();
$dialog.find('.btn-yes').click(() => { resolve(); })
$dialog.find('.btn-no').click(() => { reject(); })

})

如果你有 Promise Promise.resolve(); ,只需使用Promise.resolve();

在你的例子中:

// Show the dialog:
let $dialog = $('#dialog-confirm').show();

$dialog.find('.btn-yes').click(() => { Promise.resolve(); })
$dialog.find('.btn-no').click(() => { Promise.reject(); })
var Deferred = require('es6-deferred');
var d = new Deferred(
     (resolve, reject) => {
         // Process your Async or sync process here and
         // call resolve() and pass your data as argument when
         // it is successful
         // same for error case, just call reject() instead.
     }
);

d.then(
    (res) => {
    // res is your data passed into the resolve method the deferred promise
    // Handle your click here
    }, (err) => {
    // err is your data or error passed into the reject method
    // Handle your click here
  }
);

終於發現了重點:

事實上,deferred action 和es6-deferred包做得很好,而且效果很好。

import Deferred from 'es6-deferred';

const confirm = function(msg='confirm?') {
    const dfd = Deferred();
    const $dialog = $('#dialog-confirm').show()
    $dialog.find('.msg').text(msg);
    $dialog.find('.btn-yes').click(() => { dfd.resolve(); })
    $dialog.find('.btn-no').click(() => { dfd.reject(); })
    return dfd;
};

// ....    

實際問題是我收到了以下錯誤:

undefined:1 Uncaught (in promise) Object {}

真正的原因是我打電話給:

// Another place
confirm('Do you like to delete this item?').then(function() {
    // Do the deletion.
});

然后我點擊.btn-no取消,此時dfd.reject()被觸發,但同時promise還沒有任何catch方法來處理reject動作。

所以造成了這個問題。

當我在呼叫中添加未接拒絕功能時,一切順利。

結論:

如果 ES6 承諾在沒有注冊 CATCH 短語的情況下被拒絕,則會導致問題!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM