试图找出做承诺流程的蓝鸟方式

Trying to figure out bluebird way of doing promise flow

我正在尝试找出进行 promisification 的正确方法 - 更具体地说是使用 bluebird。我想出了一些使用新 Promises 的代码:

function createUser(data) {
  return new Promise((resolve, reject) => {

    User.createAsync(user)
        .then((doc) => {
            resolve(doc);
        })
        .catch((err) => {
            reject(err);
        });
  });
}

function create(data) {
   return new Promise((resolve, reject) => {

    User.findOneAsync({username: data.username})
        .then((user) => {
            if (user) {
                 resolve(`Username ${data.username} is already taken`);
            } else {
                createUser(data)
                    .then((user) => {
                        resolve(user);
                    })
            }
        })
        .catch((err) => {
            reject(err);
        });
   })
}

但我觉得通过这种方式我并没有从 bluebird 中得到多少,在浏览了文档之后,这似乎是一种应该避免的反模式。例如,我将如何着手使这个流程更像蓝鸟风格或总体上更好地承诺?

如果 User.createAsyncUser.findOneAsync return 承诺,您不需要将它们包装在新的承诺中。只是 return 承诺 return 由您的函数编辑:

function createUser(data) {
  return User.createAsync(data);
}

function create(data) {
  return User.findOneAsync({username: data.username})
    .then((user) => {
      if (user) {
        throw new Error(`Username ${data.username} is already taken`);
      } else {
        return createUser(data);
      }
    });
}

添加到 SimpleJ 的答案中,您可以使用异步函数执行以下操作以获得更好的代码可读性:

function createUser(data) {
  return User.createAsync(data);
}

// async functions!
//                     destructuring!
async function create({username}) {
  //                                   short literals!
  const user = await User.findOneAsync({username});
  if (user) { throw new Error(`Username ${username} is already taken`); }
  return createUser(data);
}

这为您提供了非常扁平、几乎同步的代码。注意 User.findOneAsync() 之前的 await 等待 Promise。

上面的代码等同于其他答案。异步函数需要节点 7.6 或更高版本。