如何将回调代码转换为ES6中的承诺
这个问题在这里已经有了答案:
现有的答案是延迟反模式的牺牲品。 我会避免使用这种方法,因为它不必要地冗长,并且不利用完整的Promise API。 另一个答案使用promisification。 当你无法修改使用回调风格编写的代码时(例如使用第三方脚本),只需要使用promisification。
你提出了两个问题,其次是为什么Promises按照你在给定例子中看到的方式行事。 为了找到这个问题的答案,我建议你使用关于这种性质的许多现有问题。 例如,不是Promises只是回调?
至于你的第一个问题,关于如何重构你的代码来使用Promise,这里是我的建议:
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."
})
由于函数本身并不依赖于异步操作的完成,我们可以使用帮助器方法Promise#resolve
和Promise#reject
从表示创建“矩形”对象成功或失败的函数返回一个Promise。 这些产生了一个新的Promise,它的状态分别被解析或被拒绝,并有一个值或一个错误。
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)
}
记住“.then”和“.catch”是异步的。
这是一个重要的话题。 对于功能编码以同步的寻找方式起见使用许诺的点是在移动逻辑callback
到then
的阶段。 所以,尽管你可以不应该处理承诺本身的逻辑,但在then
阶段。 这种思维方式有助于我们创建一个适用于所有特定类型回调结构的通用promisify效用函数。 在你的情况下,回调类型是Node标准错误的第一种类型。 所以根据你的代码如下
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);
}
};
一般保证函数的工作原理如下:
var moduleExports = (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);
}
};
function promisfy(fun, ...args){
return new Promise((v,x) => fun(...args, (err,data) => !!err ? x(err) : v(data)));
}
var p = promisfy(moduleExports,4,5);
p.then(val => console.log(val,val.area(),val.perimeter()), err => console.log(err));
// p.then(val => callback(null,val), err => callback(err))
链接地址: http://www.djcxy.com/p/55523.html