JavaScript-返回承诺和/或调用回调?

JavaScript-返回承诺和/或调用回调?,javascript,callback,promise,Javascript,Callback,Promise,我经常在其他人的文档中看到这样的内容: 回调是可选的,如果省略返回一个承诺 这就是我所拥有的: export function doSomeAsync(options, callback) { const useCallback = (callback && typeof callback == 'function'); const promise = new Promise((resolve, reject) => { // ---

我经常在其他人的文档中看到这样的内容:

回调是可选的,如果省略返回一个承诺

这就是我所拥有的:

export function doSomeAsync(options, callback) {

    const useCallback = (callback && typeof callback == 'function');

    const promise = new Promise((resolve, reject) => {

        // --- do async stuff here ---
        const check = (options.num === 1) ? true : false;
        setTimeout(() => {
            if (check) {
                finish(true, "Number is 1");
            } else {
                finish(false, new Error("Number is not 1"));
            }
        }, 1000);
        // ---------------------------

        function finish(ok, rtn) {
            if (useCallback) {
                if (ok) {
                    callback(null, rtn);
                } else {
                    callback(rtn, null);
                }
            } else {
                if (ok) {
                    resolve(rtn);
                } else {
                    reject(rtn);
                }
            }
        }

    });

    return (useCallback) ? false : promise;
}
函数的
finish()

我正在创建一个promise对象,不管我是否使用它

这样测试:

doSomeAsync({ num: 1 }).then((result) => {
    console.log('p result', result);
}).catch((err) => {
    console.log('p err', err);
});

doSomeAsync({ num: 1 }, (err, result) => {
    if (err) {
        console.log('cb err', err);
    } else {
        console.log('cb result', result);
    }
});

这是可行的,但我想知道这是否是最好的方法,或者其他人是否有更好、更简洁的实现方式?

如果您总是使用承诺,这可以简化,您总是在创建承诺:

export function doSomeAsync(options, callback) {
    const promise = new Promise((resolve, reject) => {
        const check = (options.num === 1) ? true : false;
        setTimeout(() => {
            if (check) {
                resolve("Number is 1");
            } else {
                reject(new Error("Number is not 1"));
            }
        }, 1000);
    });

    if (callback && typeof callback == 'function') {
        promise.then(callback.bind(null, null), callback);
    }

    return promise;
}

你的函数总是基于承诺的,而且它总是返回一个承诺。打电话的人完全可以忽略这一点。回调参数只是一个“传统回退接口”(或“替代接口”,如果您愿意),而不是使用该承诺。

您可以通过始终返回承诺来摆脱所有边缘情况,并定义一个默认回调(回调形状的标识函数),用于处理未提供回调的情况:

const genericAsync = (stuff, callback = (e, i) => e || i) => new Promise(
  (resolve, reject) => doStuffWith(stuff, resolve, reject)
)
  .then(response => callback(null, response))
  .catch(callback);

可能更适合您使用的promise库?Bluebird甚至有这样的功能。我正在运行Node v4.2.2,使用Babel for ES6(
Babel-preset-es2015 6.6.0
),但我还没有安装特定的Babel ployfill for promises。所以我猜原生节点是可以保证的。是的,这正是我所想的方法。返回
false
似乎有点浪费-而且(作为.NET开发人员和JS)从这样一个函数返回两种不同的类型似乎很奇怪。谢谢deceze。。。我已经用测试电话更新了我的问题。更新以使用您的代码后,我得到:
p结果编号为1
cb err编号为1
。回调现在只有一个参数吗?@Stephen在我上面的例子中,就是
承诺的方式。然后绑定
回调,
callback
成功时将接收一个参数,失败时将接收两个参数(
false
和error)。回调应该有
函数(result,err)
的签名。按照您喜欢的方式设计该接口。我注意到答案已更新为
promise。然后(callback.bind(null,null),callback)
生成我正在寻找的节点样式
callback(err,result)
。谢谢你Bergi&deceze!