promise save me from deep
要说到异步编程大家可能第一时间想到的就是javasrcipt, 比如在web的时候我们经常写ajax的代码去和后台交互, 或者再用node的时候,用到里面的异步版本(强调非同步)的函数。但是这种callback的写法很容易出现嵌套多次的情况出现。
以下我们考虑实现一个简单版本的文件复制(node)。
function unlyAsyncVersion(sourcePath, targetPath) {
fs.readFile(sourcePath, function (err, data) {
if (err) {
console.error(err);
} else {
fs.writeFile(targetPath, data, function (err) {
if (err) {
console.error(err);
} else {
console.log('success');
}
});
}
})
}
unlyVersion("d:/2.txt", "d:/3.txt");
在这段代码中,我们将所有的逻辑埋藏在一个个回调函数中。
function promiseUnlyVersion(sourcePath, targetPath) {
var promise = new Promise(function (reslove, reject) {
fs.readFile(sourcePath, function (err, data) {
if (err) {
reject(err);
} else {
reslove(data);
}
});
});
promise.then(function (data) {
var promise = new Promise(function (reslove, reject) {
fs.writeFile(targetPath, data, function (err) {
if (err) {
reject(err);
} else {
reslove();
}
});
})
return promise;
}, console.error).
then(function () {console.log('success');}, function (err) {console.log(err);});
}
promiseVersion("d:/2.txt", "d:/3.txt");
然而好像promise并不是救世主?所以干嘛要用它!?因为他给于我们能写出优化代码的能力
function promiseBetterVersion(sourcePath, targetPath) {
openHelper().
then(writeHelper, console.error).
then(function () { console.log("success") }, console.error);
function openHelper() {
return new Promise(function (reslove, reject) {
fs.readFile(sourcePath, function (err, data) {
if (err) {
reject(err);
} else {
reslove(data);
}
});
})
}
function writeHelper(data) {
return new Promise(function (reslove, reject) {
fs.writeFile(targetPath, data, function (err) {
if (err) {
reject(err);
} else {
reslove();
}
});
});
}
}
promiseBetterVersion("d:/2.txt", "d:/3.txt");
promise save me from exception
另一方面我们用promise的原因在于我们在写异步代码所遇到的尴尬问题。
function catchMeWithLuck() {
try {
fs.readFileSync('notExisted.txt');
} catch (err) {
console.log(err);
}
}
catchMeWithLuck();
在以上的同步版本代码中,因为文件不存在而抛出的异常,是可以捕获到的。
function catchMeWithNotLuck() {
try {
fs.readFile('notExisted.txt', function (err, data) {
if (err) {
throw err;
} else {
console.log(data);
}
});
} catch (err) {
console.log(err);
}
}
catchMeWithNotLuck();
然而在异步代码中,相同的异常却无法捕获到,这是因为函数执行的时候已经远离了异常捕获的范围
那么怎么办呢?很可以你会想到以下写法,将异常信息和正常结果通过返回值返回。
function myReadFile(filename) {
var result = {
'hasError': true,
'message': '';}
try {
result['message'] = fs.readFileSync(filename);
result['hasError'] = false;
} catch (err) {
result['message'] = err;
result['hasError'] = true;
}
}
function callMyReadFile() {
var result = myReadFile('afile');
if (result['hasError']) {
// deal with exception
} else {
// do something...
}
}
callMyReadFile()
那么Promise我们该怎么解决呢,正如我们在promiseBetterVersion中看到的那样, 通过将实际的逻辑分离出来promise的逻辑就可以很清晰.