所以在这一点上,承诺似乎有更多的牵引力,因为"最佳实践"比回调,但许多现有的库仍然使用回调。
所以给定一个已经实现了这样的回调模式的库:
library.connect(function(err) {
library.someQuery({}).exec(function(err, result) {
// some code
library.someQuery(result).exec(function(err2, result2) {
// some code
})
})
})
将这些回调包装在promises中是否有益于避免嵌套?
new Promise((resolve, reject) => {
library.connect(function(err) {
if (err) reject(err)
else resolve()
}
}).then(() => {
return new Promise((resolve, reject) => {
library.someQuery({}).exec((err, result) => {
if (err) reject(err)
else resolve(result)
}
})
}).then((result) => {
return new Promise((resolve, reject) => {
library.someQuery(result).exec(function(err2, result2) {
if (err) reject(err2)
else resolve(result2)
}
}).then((result) => {
// some code
}).catch((err) => // handle error)
没有嵌套它会更好,但它更冗长。此外,我不确定这会带来多少额外的好处。也许更好的错误处理?
答案 0 :(得分:2)
在您的第一个代码段中,您有多个位置来处理错误,而对于承诺,您只有一个。
我认为你做了一些很好的观察,也补充说使用promises会对性能产生轻微的开销。但是,如果您可以使用重复的代码,那么您可能会使用它们获得更容易调试的代码。
您还可以创建一个小函数来抽象出承诺,但请记住,这会增加一些开销:
// Non tested code, but hopes it shows a point
function make_promisable(context, method) {
return new Promise((resolve, reject) => {
context[method]((err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
// Note: The below actually seems to hide the logic in the code,
// is this any good, or harder to read/debug?
make_promisable(library, 'connect').then(() => {
return make_promisable(library.someQuery({}), 'exec');
}).then((result) => {
return make_promisable(library.someQuery(result), 'exec');
}).then((result) => {
// some code
}).catch((err) => // handle error)
答案 1 :(得分:1)
这主要是意见,但是:
如果您不止一次这样做,可能值得为公开基于Promise
的API的库编写外观:
import library from 'library';
export default {
connect() {
return new Promise((resolve, reject) => {
library.connect(function(err) {
if (err) reject(err)
else resolve()
}
}
}
// etc
}
回调地狱/嵌套是一个实现问题,不是回调的基本问题,通常可以通过分解函数而不是嵌套来改进。像async这样的图书馆使回调像Promises一样易读,或者更多。
承诺的一个优点(?)是您可以使用async/await语法(假设Babel进行转换)。在实践中,我发现这种语法很棘手,但有些人真的很喜欢它。