ES2015 相当于 $.Deferred()

ES2015 equivalent of $.Deferred()

我正在为一个项目使用 Babel,但我遇到了一个非常基本的问题。我非常习惯 jQuery 的 Deferred 对象,我正在努力寻找它的 ES2015 等价物,这就是我基本上想要的:

// file1.js
let dfd = new Promise()

function functionCalledAtSomePoint(thing) {
    dfd.resolve(thing)
}

export default { dfd }


// file2.js
import { dfd } from './file1'

dfd.then((thing) => {
    console.log('Yay thing:', thing)
})

纠正这个简单的延迟的正确方法应该是什么?

使用 royhowie 的回答进行编辑:

// file1.js
let thing
function getThing(_thing) {
    return new Promise((resolve) => {
        if (el) {
            thing = new Thing(el)
        }
        resolve(thing)
    })
}

function functionCalledAtSomePoint(el) {
    getThing(el)
}

export default { getThing }


// file2.js
import { getThing } from './file1'

getThing.then((thing) => {
    console.log('Yay thing:', thing)
})

您可以直接导出承诺(而不是函数)——就像您所做的那样——但是您只能使用它 (.then) 一次,这可能是 不是你想要的。

相反,您应该导出一个 returns a Promise:

的函数

文件1.js

import User from '../models/user'

export function getUsersFromDatabase () {
    return new Promise((resolve, reject) => {
        User.find({}, (err, users) => {
            return err ? reject(err) : resolve(users)
        })
    })
}

file2.js

import { getUsersFromDatabase } from './file1'

getUsersFromDatabase().then((users) => {
    // success
}).catch((err) => {
    // no users
})

您可以使用默认的 Promise 实现,but it much slower than 3rd party modules, e.g., bluebird(我非常推荐使用它)。

I'm very used to jQuery's Deferred objects and I'm struggling to find its ES2015 equivalent

如果您必须使用 deferred,这应该有效

function makeDeferred() {
    var res, rej;
    let dfd = new Promise(function(resolve, reject) {
        res = resolve;
        rej = reject;
    });
    dfd.resolve = res;
    dfd.reject = rej;
    return dfd;
}
let dfd = makeDeferred();

然而,重写你的代码以避免这样的混乱会更好(但并非不可避免 - 我还有 one 一段代码我无法摆脱延迟承诺, 所以我感受到你的痛苦

此 class 将允许您使用常规的 Promise 方法以及额外的 resolve(value) 方法。这应该为您提供与 jQuery.deferred().

类似的功能
function DeferredPromise() {
    var _resolve = null;
    var _reject = null;

    this.promise = new Promise(function(resolve, reject) {
        _resolve = resolve;
        _reject = reject;
    });
    this.then = function() {
        return this.promise.then(...arguments);
    }
    this.catch = function() {
        return this.promise.catch(...arguments);
    }
    this.resolve = function() {
        _resolve(...arguments);
    }
    this.reject = function() {
        _reject(...arguments);
    }
}

然后你可以用它来创建一个新的DeferredPromise:

var p = new DeferredPromise();

敬请期待:

p.then(val => {
    console.log('val(1)', val);
})

也许再等一次,你也可以用一个普通的链接Promise:

p.then(val => {
    console.log('val(2)', val);
    return 42;
 }).then(val => {
    console.log('.then(somethingElse)', val);
 })
 .catch(err => { console.error('err', err); })

随时解决:

p.resolve({ username: 'Luke.Skywalker', age: 42 });