Javascript 如何在ES6中将回调代码转换为承诺
我正在学习ES6标准,所以我从一个非常基本的示例代码开始 JavaScript中存在回调hell,所以这次我确实希望避免使用回调。但我遇到了一个问题,我真的不知道如何将回调风格的代码转换为承诺 例如,如果我有如下代码Javascript 如何在ES6中将回调代码转换为承诺,javascript,asynchronous,callback,promise,ecmascript-6,Javascript,Asynchronous,Callback,Promise,Ecmascript 6,我正在学习ES6标准,所以我从一个非常基本的示例代码开始 JavaScript中存在回调hell,所以这次我确实希望避免使用回调。但我遇到了一个问题,我真的不知道如何将回调风格的代码转换为承诺 例如,如果我有如下代码 module.exports = (x, y, callback) => { try { if (x < 0 || y < 0) { throw new Error('Rectangle dimensions are wrong.');
module.exports = (x, y, callback) => {
try {
if (x < 0 || y < 0) {
throw new Error('Rectangle dimensions are wrong.');
} else {
callback(null, {
perimeter() {
return (2 * (x + y));
},
area() {
return (x * y);
},
});
}
} catch (error) {
callback(error, null);
}
};
我的理解是,Promise
在创建后立即运行。但是我不知道为什么then
方法中的代码会最后运行。module.exports=(x,y,callback)=>{
module.exports = (x, y, callback) => {
new Promise(function(resolve, reject) {
if (x < 0 || y < 0) reject(new Error('Rectangle dimensions are wrong.'))
else resolve({
perimeter() {
return (2 * (x + y));
},
area() {
return (x * y);
}
})
})
.then(callback)
.catch(callback)
}
新承诺(功能(解决、拒绝){
如果(x<0 | | y<0)拒绝(新错误('矩形尺寸错误'))
否则解决({
周长(){
回报率(2*(x+y));
},
面积(){
返回(x*y);
}
})
})
.然后(回调)
.catch(回调)
}
请记住“.then”和“.catch”是异步的。承诺确实很好,但一开始可能会有点混乱,请检查以下代码:
module.exports = (x, y) => {
var deferred = q.defer();// this will be our promise
try {
if (x < 0 || y < 0) {
//return an error to be catched by catch method
deferred.reject(new Error('Rectangle dimensions are wrong.'));
} else {
//return the event to the next function with this value
deferred.resolve({
perimeter() {
return (2 * (x + y));
},
area() {
return (x * y);
},
});
}
} catch (error) {
deferred.reject(error);
}
return deferred.promise; //Here return the promise
};
//You will use it like this
module(x,y)
.then(callback)
.then(function(data){
})
.catch(function(error){
});
module.exports=(x,y)=>{
var deferred=q.deferred();//这将是我们的承诺
试一试{
if(x<0 | | y<0){
//返回要由catch方法捕获的错误
拒绝(新错误('矩形尺寸错误');
}否则{
//使用此值将事件返回到下一个函数
推迟,解决({
周长(){
回报率(2*(x+y));
},
面积(){
返回(x*y);
},
});
}
}捕获(错误){
延迟。拒绝(错误);
}
return deferred.promise;//此处返回承诺
};
//你会像这样使用它
模块(x,y)
.然后(回调)
.then(功能(数据){
})
.catch(函数(错误){
});
在我的示例中,当您调用模块时,您将立即获得承诺,但代码尚未执行,在代码执行后,您将在“then”方法中获得事件,或者如果捕获中发生了什么事情
我真的很喜欢q库来处理承诺,让您能够控制如何返回错误,并在发生错误时停止链。基本上,您可以更好地控制您的函数流
希望对您有所帮助这是一个重要的话题。为了以同步的方式进行功能编码,使用promises的目的是将
回调
中的逻辑移动到然后
阶段。因此,尽管可以,但您不应该在承诺本身中处理逻辑,而是在然后阶段。这种思维方式帮助我们创建一个通用的promisify实用程序函数,它适用于所有特定类型的回调结构。在您的情况下,回调类型是节点标准错误第一种类型。所以按照下面的代码
module.exports = (x, y, callback) => {
try {
if (x < 0 || y < 0) {
throw new Error('Rectangle dimensions are wrong.');
} else {
callback(null, {
perimeter() {
return (2 * (x + y));
},
area() {
return (x * y);
},
});
}
} catch (error) {
callback(error, null);
}
};
module.exports=(x,y,回调)=>{
试一试{
if(x<0 | | y<0){
抛出新错误('矩形尺寸错误');
}否则{
回调(null{
周长(){
回报率(2*(x+y));
},
面积(){
返回(x*y);
},
});
}
}捕获(错误){
回调(错误,空);
}
};
一般承诺功能应如下所示:
var moduleExports=(x,y,回调)=>{
试一试{
if(x<0 | | y<0){
抛出新错误('矩形尺寸错误');
}否则{
回调(null{
周长(){
回报率(2*(x+y));
},
面积(){
返回(x*y);
},
});
}
}捕获(错误){
回调(错误,空);
}
};
函数promisfy(乐趣,…参数){
返回新承诺((v,x)=>fun(…args,(err,data)=>!!err?x(err):v(data));
}
var p=promisfy(模块出口,4,5);
p、 然后(val=>console.log(val,val.area(),val.permiture()),err=>console.log(err));
//p.then(val=>callback(null,val),err=>callback(err))
现有的答案会成为问题的牺牲品。我会避免使用这种方法,因为它不必要地冗长,并且没有利用FullPromise API。另一个答案是使用Promission。只有当您无法更改使用回调样式编写的代码(例如,使用第三方脚本)时,才需要使用Promission
你在问两个问题,第二个问题是,为什么承诺会像你在给定的例子中看到的那样。为了找到这个问题的答案,我建议你使用许多现有的关于这个性质的问题。比如说,
关于第一个问题,即如何重构代码以使用承诺,我的建议如下:
module.exports = (x, y) => {
if (x < 0 || y < 0) {
return Promise.reject(new Error('Rectangle dimensions are wrong.'));
} else {
return Promise.resolve({
perimeter() {
return (2 * (x + y));
},
area() {
return (x * y);
},
});
}
};
// e.g. success
createRectangle(10, 10)
.then(rect => {
console.log(rect.area()) //=> 100
})
// e.g. failure
createRectangle(-1, -1)
.catch(err => {
console.log(err) //=> "Error: Rectangle dimensions are wrong."
})
module.exports=(x,y)=>{
if(x<0 | | y<0){
返回承诺。拒绝(新错误('矩形尺寸错误');
}否则{
还愿({
周长(){
回报率(2*(x+y));
},
面积(){
返回(x*y);
},
});
}
};
//例如成功
createRectangle(10,10)
.然后(rect=>{
console.log(rect.area())/=>100
})
//例如失败
createRectangle(-1,-1)
.catch(错误=>{
console.log(err)//=>“错误:矩形尺寸错误。”
})
由于函数本身并不依赖于异步操作的完成,我们可以使用helper方法,并从函数返回一个承诺,表示创建“矩形”对象的成功或失败。这些产生了一个新的承诺,其状态被解析或拒绝,分别带有一个值或一个错误。如果您阅读了承诺/a+的规范,请特别注意2.2.4和相关的注释3.1-基本上是。然后回调是异步的,这正是我想要的。我会查看其他一些关于承诺的帖子。
module.exports = (x, y) => {
if (x < 0 || y < 0) {
return Promise.reject(new Error('Rectangle dimensions are wrong.'));
} else {
return Promise.resolve({
perimeter() {
return (2 * (x + y));
},
area() {
return (x * y);
},
});
}
};
// e.g. success
createRectangle(10, 10)
.then(rect => {
console.log(rect.area()) //=> 100
})
// e.g. failure
createRectangle(-1, -1)
.catch(err => {
console.log(err) //=> "Error: Rectangle dimensions are wrong."
})