【问题标题】:How do I defer an ES6 promise like jquery Deferred?如何推迟像 jquery Deferred 这样的 ES6 承诺?
【发布时间】:2016-11-19 23:18:33
【问题描述】:

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 找到一个延迟接口。

于是我搜索了一个ES6 EDITION的deferred:

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

但我仍然收到错误:

undefined:1 未捕获(承诺中)对象 {}

实际上,代码只是使用闭包将内部resolvereject 函数保留在外部:

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 操作?

【问题讨论】:

  • 使用Promise的目的是什么? .then() 没有出现在问题中?
  • 这个问题已经被问过很多次了。延迟对象没有内置到 ES6 Promise 中,因为正如 here 所解释的那样,它根本不需要。而且,如果你想制造一个,只需要几行 ES6 代码就可以做到。
  • 其实我用的是vuex,我在vuex的actions中创建promise弹出对话框,但是需要在组件中resolve或者reject这个promise。
  • Promise 在问题的javascript 处被解决或拒绝,尽管没有值或原因作为参数传递?
  • 如何在几行 ES6 承诺代码中创建延迟:stackoverflow.com/questions/37651780/…(尽管您永远不需要这样做)。

标签: javascript jquery ecmascript-6 deferred es6-promise


【解决方案1】:

在承诺中移动 jquery 语句

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

})

【讨论】:

  • 我使用vue框架,所以触发点被分成不同的代码文件。
  • 我将dfd或promise对象返回到外面,并在其他脚本文件中触发resolve动作。
  • 你可以将整个函数从另一个文件传递给 promise let promise = new Promise(yourfunction_imported)
  • 这破坏了我的设计。所以我要求解决方案。
  • @fish_ball 为什么将对话框事件附加到与创建承诺不同的文件中的代码?请在您的问题中清楚地解释这一点(最好使用代码示例)。到目前为止,您只在应该询问如何解决问题时询问我们如何进行具体实施。
【解决方案2】:
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
  }
);

【讨论】:

  • 10行代码使用节点模块?提醒我这一点:theregister.co.uk/2016/03/23/npm_left_pad_chaos(使用此模块的人都应该破坏他们的项目,这是一个非常容易实现的实用功能,就像这样)。
  • @Disfigure - 我认为关键是从 ES6 承诺中创建一个 deferred 只需要 8 行代码,如下所示:stackoverflow.com/questions/37651780/…
  • 我的示例没有使用该模块 - 它最初是编写的代码。它是类似的代码,因为这就是你的做法。
  • 不回答问题,因为它不是原生 es6 承诺解决方案。
【解决方案3】:

对于那些从 Google 来到这里的人来说,值得一提的是 ES6 承诺很好,我经常使用它们。但是,在某些用例中,延迟模式会导致代码显着减少。在大多数情况下,您可能应该只使用 ES6 承诺,但在那些延迟模式有意义的特殊情况下,它很容易包装 ES6 承诺。在我看来,包含一个节点模块似乎太过分了。

function generateDeferredPromise() {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    [resolve, reject] = [res, rej];
  });
  return {promise, reject, resolve};
}

【讨论】:

  • 为什么需要 IIFE?
  • @forresthopkinsa 似乎不需要。
猜你喜欢
  • 2017-02-01
  • 2015-03-27
  • 2023-03-21
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多