繁体   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