JavaScript - 返回承诺和/或调用回调?
Posted
技术标签:
【中文标题】JavaScript - 返回承诺和/或调用回调?【英文标题】:JavaScript - Return promise AND/OR call callback? 【发布时间】:2016-08-18 16:33:39 【问题描述】:我经常在其他人的文档中看到类似的内容:
回调是可选的,如果省略则返回一个承诺。
这就是我所拥有的:
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()
函数只是避免了散布在各处的大量 if...
语句。
我正在创建一个 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);
);
这可行,但我想知道这是否是最好的方法,或者其他人是否有更好、更简洁的实现..?
【问题讨论】:
可能更适合codereview.stackexchange.com 你使用的是什么承诺库? Bluebird 甚至为此提供了 a dedicated function。 我正在运行 Node v4.2.2,使用 Babel for ES6 (babel-preset-es2015 6.6.0
),但我还没有为 Promise 安装特定的 babel ployfill。所以我猜是原生 Node 承诺。
【参考方案1】:
您可以通过始终返回一个承诺来摆脱所有边缘情况,并定义一个默认回调(一个回调形状的标识函数)来处理不提供回调的情况:
const genericAsync = (stuff, callback = (e, i) => e || i) => new Promise(
(resolve, reject) => doStuffWith(stuff, resolve, reject)
)
.then(response => callback(null, response))
.catch(callback);
【讨论】:
【参考方案2】:如果你总是简单地使用你总是在创建的承诺,这可以简化:
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;
你的函数总是基于 Promise 的,事实上它总是返回一个 Promise。调用者可以随意忽略它。回调参数只是使用该承诺的“遗留后备接口”(或“替代接口”,如果您愿意的话)。
【讨论】:
是的,这正是我所想的方法。返回false
似乎有点浪费——而且(作为 .NET 开发人员和 JS)从这样的函数返回两种不同的类型似乎很奇怪。
谢谢 deceze... 我已经用测试电话更新了我的问题。更新以使用您的代码后,我得到:p result Number is 1
和 cb err Number is 1
。回调现在是否只有一个参数?
@Stephen 在我上面的示例中,promise.then
回调绑定的方式,callback
将在成功的情况下接收一个参数,在失败的情况下接收两个参数(false
和错误) .回调应该有function (result, err)
的签名。以您喜欢的方式设计该界面。
我注意到答案已更新为 promise.then(callback.bind(null, null), callback)
以生成我正在寻找的节点样式 callback(err, result)
。谢谢Bergi & deceze!以上是关于JavaScript - 返回承诺和/或调用回调?的主要内容,如果未能解决你的问题,请参考以下文章