看到精华里有篇文章叫做 如何让异步接口同时支持 callback 和 promise,少爷打算发表少爷在cnode的第一篇文章,无奈取名是个技术活,偏偏少爷又只有初中文凭,只好在原文标题上加了几个字,希望兄台莫怪👻
实现
我文采不好就不啰嗦了,直接上代码:
export const createPromiseCallback = () => {
let cb;
if (!global.Promise) {
cb = () => {};
cb.promise = {};
const throwPromiseNotDefined = () => {
throw new Error(
'Your Node runtime does support ES6 Promises. ' +
'Set "global.Promise" to your preferred implementation of promises.');
};
Object.defineProperty(cb.promise, 'then', { get: throwPromiseNotDefined });
Object.defineProperty(cb.promise, 'catch', { get: throwPromiseNotDefined });
return cb;
}
const promise = new global.Promise((resolve, reject) => {
cb = (err, data) => {
if (err) return reject(err);
return resolve(data);
};
});
cb.promise = promise;
return cb;
};
用法
function xxx(p1, p2, fn) {
fn = fn || createPromiseCallback();
// your code here...
return fn.promise;
}
栗子
// define
User.createPost = (id, post, fn) => {
fn = fn || createPromiseCallback();
User.findById(id, (err, user) => {
if (err) return fn(err);
if (!user) return fn(new Error('User is not found.'));
user.post.create(post, (err, post)=> {
if (err) return fn(err);
fn(null, post);
});
});
return fn.promise;
}
// use callback
User.createPost(userId, post, (err, instance) => {
// do something...
});
// use promise
User.createPost(userId, post).then((instance) =>{
// do something...
}).catch((err) => {
// handle error
});
把promise的逻辑单独拆出来,在需要兼容的函数里只要判断fn就行,是不是很优雅,少爷可不是标题党! 相信写过loopback的童鞋看着一定很熟悉,其实代码就出自loopback哦!