Quantcast
Channel: CNode:Node.js专业中文社区
Viewing all articles
Browse latest Browse all 14821

如何让异步接口更优雅的同时支持 callback 和 promise

$
0
0

看到精华里有篇文章叫做 如何让异步接口同时支持 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哦!


Viewing all articles
Browse latest Browse all 14821

Trending Articles