Как конвертировать метод Водопад в обещание
Ниже приведен фрагмент кода, использующий метод 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+ без каких-либо флагов. Увидеть:
Для большего количества примеров см. Этот ответ:
И для получения дополнительной информации см. Обновления к этому ответу для получения дополнительной информации: