我正在使用bluebird处理异步脚本加载器,我正在努力将错误传递到我可以捕获它的位置。
当加载文件时,我正在调用名为declare
的方法,如下所示:
declare("storage", [
{"name": 'util', "src": '../src/util.js'}
], function (util) {
var storage = {};
//...stuff with util
return storage;
});
declare
为:
declare = function (name, dependency_list, callback) {
var resolver;
// digest promises returned for each module
function digestDependencyArray(my_dependency_array) {
var i, len, response_array;
len = my_dependency_array.length;
for (i = 0, response_array = []; i < len; i += 1) {
response_array[i] = my_dependency_array[i];
}
return Promise.all(response_array);
}
// resolve request promise
function resolveDependencyArray(my_fullfillment_array) {
var return_value = callback.apply(window, my_fullfillment_array);
// window.exports must be used when integrating commonjs modules
if (!return_value) {
return_value = window.exports;
}
resolver(return_value);
}
// START: set callback to (resolved) callback or new promise
my_lib.callback_dict[name] = my_lib.callback_dict[name] ||
new Promise(function (resolve) {
resolver = resolve;
if (dependency_list.length === 0) {
return resolver(callback.apply(window));
}
return request(dependency_list)
.then(digestDependencyArray)
.then(resolveDependencyArray)
// DON'T CATCH HERE...
.catch(console.log);
});
};
这一切都运行良好,除了我不想在此时使用catch
语句,因为错误处理应该在不同的模块中完成(console.log只是一个标志)。
问题:
如何将我的declare
方法中出现的错误传播到更高的承诺链?我希望在我的catch
调用中添加一个declare
处理程序会有所帮助,但这会打破整个脚本 - 我假设因为我从声明调用返回模块而不是有效的promise响应。
感谢您的任何提示!
修改:
我打电话来声明:
request([{"name": "foo", "src": "path/to/foo.js"}])
.spread(foo) {
})
.catch(function (e) {
console.log(e);
})
request
会将文件加载到一个promise中,该文件在加载文件时会被解析,并以回调的方式运行文件内容,然后调用上面的declare
方法。不知怎的,我的错误在途中丢失了(代码here)。让我们看看我是否可以catch
在某个地方......
编辑2 :
改为内部声明:
function resolveDependencyArray(my_fullfillment_array) {
var return_value = callback.apply(window, my_fullfillment_array);
if (!return_value) {
return_value = window.exports;
}
return return_value;
}
function handler() {
if (dependency_list.length === 0) {
Promise.resolve(callback.apply(window));
} else {
return request(dependency_list)
.then(digestDependencyArray)
.then(resolveDependencyArray)
.catch(function (e) {
reject(e);
});
}
}
clappjs.callback_dict[name] = clappjs.callback_dict[name] || handler();
虽然我没有错误,但是请求多个模块不起作用,因为模块被返回undefined
,所以:
request(["foo", "bar", "baz"]).spread(function (foo, bar, baz) {
console.log(foo); // undefined
console.log(bar); // {} OK
console.log(baz); // undefined
});
与new Promise
加载后正确返回文件。
答案 0 :(得分:12)
您需要重新抛出错误!
.catch(function(e) {
console.log(e); // calling it as a method, btw
throw e;
})
您还可以尝试使用tap
,或在添加.catch(console.log)
之前返回您在链中的承诺。
此外,您使用的是manually-construct-promise antipattern,而实际上您根本不需要call the Promise
constructor。只需使用您已有的承诺!您似乎想要这样做:
my_lib.callback_dict[name] = my_lib.callback_dict[name] || (
dependency_list.length === 0
? Promise.resolve()
: request(dependency_list)
.then(digestDependencyArray)
.then(resolveDependencyArray) // don't call a global `resolver()`
// just `return` the value!
);
答案 1 :(得分:1)
提供request([])
返回[]
和callback
高兴地接受[]
,然后declare()
应简化如下:
declare = function(name, dependency_list, callback) {
if(!my_lib.callback_dict[name]) {
my_lib.callback_dict[name] = request(dependency_list).then(function(arr) {
return Promise.all(arr);
}).then(function(arr) {
return callback.apply(window, arr) || window.exports;
});
}
return my_lib.callback_dict[name];
};
然后确保callback
返回虚假的内容,例如null
表示应使用window.exports
的条件。
我可能已做过一两次非自愿的假设,但我确信接近上述情况应该可以胜任。
就个人而言,我会在电话中处理任何错误。
declare(name, dependency_list, callback).then(handleSucces).then(null, handleError);
通过在单独的.then
中处理成功和失败,handleSuccess
中引发的任何未捕获的错误也会被handleError
捕获。