如何将Waterfall方法转换为promise

Abh*_*wal -3 javascript waterfall callback node.js promise

下面是使用async-waterfall方法的代码段.我怎么能用诺言转换这个.

async.waterfall([
    function(callback){
     User.update({username: user.username}, {$set: update_list}, function(err, a_user) {
      if (err) {
        err = new Error();
        err.code = 400;
        err.message = "Unexpected error occurred."
        callback(err)
      }
      if (!a_user) {
        err = new Error();
        err.code = 400;
        err.message = "User not found."
        callback(err)
      }else{
        callback(null, "updated", user_image);
      }
    })
   }, function(message, user_image, callback){
    if(user_image == undefined){
      callback(null, "done")
    }else{
      Bean.update({username: user.username, status:"Active"}, {$set: {user_image:user_image}},{multi:true},function(err, beanUpdated){
        if(err){
          err = new Error();
          err.code = 400;
          err.message = "Unexpected error occurred."
          callback(err)
        }else{
          callback(null, "done"); 
        }
      })
    }
  }
  ], function(err, result){
    if(err){
      return res.json({code:err.code, message:err.message})
    }else{
      return res.json({code:200, message:"Successfully updated profile."})
    }
  })
Run Code Online (Sandbox Code Playgroud)

我通常使用异步模块的瀑布和系列方法来同步我的Node js代码.帮助我从异步切换到承诺.

rsp*_*rsp 6

我不会为你重写你的代码,但我会为你提供足够的信息,以便你可以用3种不同的风格自己做,并举例说明这些概念.重写代码将为您提供熟悉承诺的好机会.

您可以使用函数返回promises并从回调中返回这些promise,而不是使用回调函数和组合它们的函数,以便在下一个回调中使用这些promise的已解析值:async.waterfallthenthen

f1().then((a) => {
  return f2(a);
}).then((b) => {
  return f3(b);
}).then((c) => {
  // you can use c which is the resolved value
  // of the promise returned by the call to f3(b)
}).catch((err) => {
  // handle errors
});
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中可以简化为:

f1()
  .then(a => f2(a))
  .then(b => f3(b))
  .then((c) => {
    // use c here
  }).catch((err) => {
    // handle errors
  });
Run Code Online (Sandbox Code Playgroud)

甚至这个:

f1().then(f2).then(f3).then((c) => {
  // use c here
}).catch((err) => {
  // handle errors
});
Run Code Online (Sandbox Code Playgroud)

或者你可以很容易地和async/ 一起组成它们await:

let a = await f1();
let b = await f2(a);
let c = await f3(b);
// ...
Run Code Online (Sandbox Code Playgroud)

甚至在这种特殊情况下:

let c = await f3(await f2(await f1()));
Run Code Online (Sandbox Code Playgroud)

在这里你用try/ 处理错误catch:

try {
  let c = await f3(await f2(await f1()));
  // use the c here
} catch (err) {
  // handle errors
}
Run Code Online (Sandbox Code Playgroud)

代码使用await必须在用async关键字声明的函数内部,但你可以通过包装这样的东西在任何地方使用它:

// not async function - cannot use await here
(async () => {
  // this is async function - you can use await here
})();
// not async function again - cannot use await
Run Code Online (Sandbox Code Playgroud)

(async () => { ... })()表达式本身返回解析为异步函数的返回值,或是一个内部抛出的异常拒绝的承诺.

请注意,在上面的示例中,每个函数都可以轻松地依赖于前一个函数返回的已解析promise的值,即确切的用例,async.waterfall但我们没有使用任何库,只有该语言的本机特性.

await语法是在节点V7.0 +在和谐的标志和V7.6 +不带任何标志可用.看到:

有关更多示例,请参阅此答案:

有关更多信息,请参阅此答案的更新: