我正在使用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
方法到更高的承诺链?我曾希望在我的declare
调用上添加catch
处理程序会有所帮助,但这破坏了整个脚本-我假设是因为我从我的声明调用中返回模块,而不是一个有效的承诺响应。
谢谢你的建议!
编辑:
我调用declare from this:
request([{"name": "foo", "src": "path/to/foo.js"}])
.spread(foo) {
})
.catch(function (e) {
console.log(e);
})
request
将在一个promise中加载文件,该promise在文件加载时得到解析,并将文件内容作为回调运行,然后调用上述declare
方法。不知何故,我的错误丢失的方式(代码在这里)。让我们看看是否可以在某个地方catch
…
编辑2 :
在declare:
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
在加载后正确返回文件
您需要重新抛出错误!
.catch(function(e) {
console.log(e); // calling it as a method, btw
throw e;
})
您也可以尝试使用tap
,或者在添加.catch(console.log)
之前返回您在链中的承诺。
此外,您正在使用手动构造承诺反模式,而实际上您不应该调用Promise
构造函数。只要使用你已经拥有的承诺!您似乎想这样做:
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!
);
假设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
s中处理成功和失败,handleSuccess
中抛出的任何未捕获的错误也将被handleError
捕获。