Как конвертировать метод Водопад в обещание

Ниже приведен фрагмент кода, использующий метод 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."})
    }
  })

Я обычно использую метод водопада и серии асинхронного модуля для синхронизации моего кода Node js. Помоги мне перейти от асинхронного к обещанию.

1 ответ

Я не буду переписывать ваш код для вас, но предоставлю вам достаточно информации, чтобы вы могли сделать это самостоятельно в 3 разных стилях с примерами, демонстрирующими концепции. Переписав ваш код, вы получите хорошую возможность ознакомиться с обещаниями.

Вместо того, чтобы функции принимать обратные вызовы и составлять их с async.waterfall Вы можете использовать функции, возвращающие обещания и возвращать эти обещания из then обратные вызовы, чтобы использовать разрешенные значения этих обещаний в следующем then Перезвоните:

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
});

Который в этом простом примере может быть упрощен до:

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

Или даже это:

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

Или вы можете очень легко составить их вместе с async/await:

let a = await f1();
let b = await f2(a);
let c = await f3(b);
// ...

Или даже это в данном конкретном случае:

let c = await f3(await f2(await f1()));

Здесь вы обрабатываете ошибки с try/catch:

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

Использование кода 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

(async () => { ... })() Само выражение возвращает обещание, которое разрешается в возвращаемом значении асинхронной функции или отклоняется, за исключением брошенного внутри.

Обратите внимание, что в приведенных выше примерах каждая функция может легко зависеть от значения разрешенного обещания, возвращенного предыдущей функцией, то есть от точного варианта использования async.waterfall но мы не используем какую-либо библиотеку для этого, только нативные возможности языка.

await синтаксис доступен в Node v7.0+ с флагом гармонии и v7.6+ без каких-либо флагов. Увидеть:

Для большего количества примеров см. Этот ответ:

И для получения дополнительной информации см. Обновления к этому ответу для получения дополнительной информации:

Другие вопросы по тегам