gpt4 book ai didi

javascript - 在模块之间共享 promise 与拥有多个 promise

转载 作者:行者123 更新时间:2023-11-30 12:27:35 24 4
gpt4 key购买 nike

我正在使用 Kris Kowal 的 Q 库实现带有 Controller 和存储库的 Node.js 逻辑。我感觉我在下面的示例中使用 promise 的方式不正确。但是我找不到关于如何通过多层或函数使用 promise 的正确模式的任何指导。

我做的对吗?实现此逻辑的正确方法是什么?

//模块:存储库

exports.findOne = function (query) {
var deferred = Q.defer();

db.query(query, function (err, data) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(data);
}
});

return deferred.promise;
};

//模块:用户

var isEmailAvailable = function (value) {
var deferred = Q.defer();

Repository.findOne({email: value})
.then(function (user) {
if (user) {
if (self.id === user.id) {
deferred.resolve(true);
}
else {
deferred.resolve(false);
}
} else {
deferred.resolve(true);
}
})
.fail(function (err) {
deferred.reject(err);
});

return deferred.promise;
};

this.save = function () {
var deferred = Q.defer();

isEmailAvailable(this.email)
.then(function (result) {
if (result) {
Repository.upsert(self)
.then(function (user) {
deferred.resolve(user); //--- Yey!!!
}).fail(function () {
deferred.reject('Account save error')
});
} else {
deferred.reject('The email is already in use');
}
}).fail(function () {
deferred.reject('Account validation error')
});

return deferred.promise;
};

最佳答案

I have a feeling that the way I use promises is not correct

是的,您使用 deferred antipattern很多。 Promises do chain ,这意味着您可以简单地从 then 回调中返回值甚至 promise ,并且 .then() 调用将为那些返回值。当您throw 时,result promise 将被拒绝。

您在存储库模块中使用 deferreds 是正确的,因为 db.query api 需要是 promisified .但是用户模块可以大幅收缩,当你已经有 promise 时,你不需要使用任何延迟。

function isEmailAvailable(value) {
return Repository.findOne({email: value})
.then(function (user) {
return !user || self.id === user.id;
});
}

this.save = function() {
return isEmailAvailable(this.email)
.then(function (result) {
if (result) {
return Repository.upsert(self)
.then(null, function(err) {
throw new Error('Account save error');
});
} else {
throw new Error('The email is already in use');
}
}, function(err) {
throw new Error('Account validation error');
});
};

或者,按照@Roamer-1888 的建议,使用 exceptions for control flow :

function isEmailAvailable(value) {
return Repository.findOne({email: value})
.then(function (user) {
if (user && self.id !== user.id)
throw new Error('The email is already in use');
}, function(err) {
throw new Error('Account validation error');
});
}

this.save = function() {
return isEmailAvailable(this.email)
.then(function () {
return Repository.upsert(self)
.then(null, function(err) {
throw new Error('Account save error');
});
});
};

关于javascript - 在模块之间共享 promise 与拥有多个 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28844132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com