如何使用js Promise消除厄运金字塔
how to use js Promise to eliminate pyramid of doom
我正在尝试了解如何使用 js Promise api 折射具有大量嵌套 IF 的代码。
从本地存储获取 JSON 对象时的示例,正常代码如下所示
function $storage(key,default) {
let json = localStorage.getItem(key);
if(json === null) return default;
try{ // <-- need try catch in case value was not valid json object
json = JSON.parse(json);
} catch (e) {
json = default;
}
return typeof json === 'object' ? json : default;
}
这段代码的可读性不是很好。所以我想也许我可以利用 js Promise 将其重写为
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then( ls => JSON.parse(ls.getItem(key)) )
.then( json => typeof json === 'object' ? json : HOW_TO_THROW_ERROR() )
//on more validation step if needed
.then( json => typeof json === 'object' ? json : HOW_TO_THROW_ERROR() )
.then( valid_json => { return = valid_json } )
.catch( error => { ret = default; console.warn('json invalid',e); } );
return ret;
}
现在我想知道如何在 then 中抛出异常,以便 catch 可以捕获它并执行默认值?
这是对 js 的有效使用吗?我是否在浪费性能
在 JavaScript 中,您可以使用关键字 throw
来抛出任何错误。
来自 MDN 的示例:
throw "Error2"; // generates an exception with a string value
throw 42; // generates an exception with the value 42
throw true; // generates an exception with the value true
throw new Error("Error");
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then( ls => JSON.parse(ls.getItem(key)) )
.then( json => typeof json === 'object' ? json : throw new Error("invalid json") )
//on more validation step if needed
.then( json => typeof json === 'object' ? json : throw new Error("invalid json") )
.then( valid_json => { return = valid_json } )
.catch( err => { ret = default; console.warn(err.message); } );
return ret;
}
您基本上可以只执行以下操作,因为如果解析失败,它将被自动捕获。
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then(ls => JSON.parse(ls.getItem(key)) )
.then(valid_json => { return = valid_json } )
.catch(err => { ret = default; console.warn(err.message); } );
return ret;
}
您可以使用 Promise.reject()
来抛出错误:
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then( ls => JSON.parse(ls.getItem(key)) )
.then( json => typeof json === 'object' ? json : Promise.reject("invalid json") )
.then( valid_json => { return = valid_json } )
.catch( err => { ret = default; console.warn(err.message); } );
return ret;
}
尽管我发现以下内容更加清晰和惯用。
function $storage(key,default) {
let json = localStorage.getItem(key);
if(json === null || typeof json !== 'object') json = default;
try{
json = JSON.parse(json);
} catch (e) {
json = default;
} finally {
return json
}
}
如您所知,Promises 用于异步计算。任何其他用途可能会使其他程序员感到困惑。
可以使用thrown来抛出错误,然后在catch方法中处理
var p1 = new Promise(function(resolve, reject) {
resolve('Success');
});
p1.then(function(value) {
console.log(value); // "Success!"
throw 'oh, no!';
}).catch(function(e) {
console.log(e); // "oh, no!"
}).then(function(){
console.log('after a catch the chain is restored');
}, function () {
console.log('Not fired due to the catch');
});
// The following behaves the same as above
p1.then(function(value) {
console.log(value); // "Success!"
return Promise.reject('oh, no!');
}).catch(function(e) {
console.log(e); // "oh, no!"
}).then(function(){
console.log('after a catch the chain is restored');
}, function () {
console.log('Not fired due to the catch');
});
但是如果在异步函数中抛出一些错误,则永远不会调用 catch。
// Errors thrown inside asynchronous functions will act like uncaught errors
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
throw 'Uncaught Exception!';
}, 1000);
});
p2.catch(function(e) {
console.log(e); // This is never called
});
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
我看到的问题只是关于 JSON.parse
,将它包装在一个更有用的函数中你会得到类似的东西:
function safeParse(x) {
try {
return JSON.parse(x);
} catch(e) {
// Log the problem
return null;
}
}
function parmval(key, defval) {
var json = safeParse(localStorage.get(key));
return (typeof json === "object") ? json : defval;
}
Promise 是关于异步操作的,而不是 IF。
我正在尝试了解如何使用 js Promise api 折射具有大量嵌套 IF 的代码。
从本地存储获取 JSON 对象时的示例,正常代码如下所示
function $storage(key,default) {
let json = localStorage.getItem(key);
if(json === null) return default;
try{ // <-- need try catch in case value was not valid json object
json = JSON.parse(json);
} catch (e) {
json = default;
}
return typeof json === 'object' ? json : default;
}
这段代码的可读性不是很好。所以我想也许我可以利用 js Promise 将其重写为
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then( ls => JSON.parse(ls.getItem(key)) )
.then( json => typeof json === 'object' ? json : HOW_TO_THROW_ERROR() )
//on more validation step if needed
.then( json => typeof json === 'object' ? json : HOW_TO_THROW_ERROR() )
.then( valid_json => { return = valid_json } )
.catch( error => { ret = default; console.warn('json invalid',e); } );
return ret;
}
现在我想知道如何在 then 中抛出异常,以便 catch 可以捕获它并执行默认值?
这是对 js 的有效使用吗?我是否在浪费性能
在 JavaScript 中,您可以使用关键字 throw
来抛出任何错误。
来自 MDN 的示例:
throw "Error2"; // generates an exception with a string value
throw 42; // generates an exception with the value 42
throw true; // generates an exception with the value true
throw new Error("Error");
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then( ls => JSON.parse(ls.getItem(key)) )
.then( json => typeof json === 'object' ? json : throw new Error("invalid json") )
//on more validation step if needed
.then( json => typeof json === 'object' ? json : throw new Error("invalid json") )
.then( valid_json => { return = valid_json } )
.catch( err => { ret = default; console.warn(err.message); } );
return ret;
}
您基本上可以只执行以下操作,因为如果解析失败,它将被自动捕获。
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then(ls => JSON.parse(ls.getItem(key)) )
.then(valid_json => { return = valid_json } )
.catch(err => { ret = default; console.warn(err.message); } );
return ret;
}
您可以使用 Promise.reject()
来抛出错误:
function $storage (key, default) {
let ret;
let promise = new Promise( (y,n) => y(localStorage) )
.then( ls => JSON.parse(ls.getItem(key)) )
.then( json => typeof json === 'object' ? json : Promise.reject("invalid json") )
.then( valid_json => { return = valid_json } )
.catch( err => { ret = default; console.warn(err.message); } );
return ret;
}
尽管我发现以下内容更加清晰和惯用。
function $storage(key,default) {
let json = localStorage.getItem(key);
if(json === null || typeof json !== 'object') json = default;
try{
json = JSON.parse(json);
} catch (e) {
json = default;
} finally {
return json
}
}
如您所知,Promises 用于异步计算。任何其他用途可能会使其他程序员感到困惑。
可以使用thrown来抛出错误,然后在catch方法中处理
var p1 = new Promise(function(resolve, reject) {
resolve('Success');
});
p1.then(function(value) {
console.log(value); // "Success!"
throw 'oh, no!';
}).catch(function(e) {
console.log(e); // "oh, no!"
}).then(function(){
console.log('after a catch the chain is restored');
}, function () {
console.log('Not fired due to the catch');
});
// The following behaves the same as above
p1.then(function(value) {
console.log(value); // "Success!"
return Promise.reject('oh, no!');
}).catch(function(e) {
console.log(e); // "oh, no!"
}).then(function(){
console.log('after a catch the chain is restored');
}, function () {
console.log('Not fired due to the catch');
});
但是如果在异步函数中抛出一些错误,则永远不会调用 catch。
// Errors thrown inside asynchronous functions will act like uncaught errors
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
throw 'Uncaught Exception!';
}, 1000);
});
p2.catch(function(e) {
console.log(e); // This is never called
});
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
我看到的问题只是关于 JSON.parse
,将它包装在一个更有用的函数中你会得到类似的东西:
function safeParse(x) {
try {
return JSON.parse(x);
} catch(e) {
// Log the problem
return null;
}
}
function parmval(key, defval) {
var json = safeParse(localStorage.get(key));
return (typeof json === "object") ? json : defval;
}
Promise 是关于异步操作的,而不是 IF。