Javascript 加载文件后,如何将承诺错误传播到更高的承诺级别?
我正在使用一个异步脚本加载器工作,我正在努力将错误传递到可以捕获它的地方 加载文件时,我调用名为Javascript 加载文件后,如何将承诺错误传播到更高的承诺级别?,javascript,asynchronous,error-handling,promise,bluebird,Javascript,Asynchronous,Error Handling,Promise,Bluebird,我正在使用一个异步脚本加载器工作,我正在努力将错误传递到可以捕获它的地方 加载文件时,我调用名为declare的方法,如下所示: declare("storage", [ {"name": 'util', "src": '../src/util.js'} ], function (util) { var storage = {}; //...stuff with util return storage; }); 声明为: declare = func
declare
的方法,如下所示:
declare("storage", [
{"name": 'util', "src": '../src/util.js'}
], function (util) {
var storage = {};
//...stuff with util
return storage;
});
声明
为:
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);
});
};
request
将在一个promise中加载文件,该promise在加载文件时得到解析,并以回调的形式运行文件内容,然后调用上述declare
方法。不知何故,我的错误在途中丢失了(代码)。让我们看看我是否能在某处捕捉到它
编辑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();
虽然我没有收到错误,但请求多个模块不起作用,因为返回的模块未定义,因此:
request(["foo", "bar", "baz"]).spread(function (foo, bar, baz) {
console.log(foo); // undefined
console.log(bar); // {} OK
console.log(baz); // undefined
});
与新承诺相比,加载后正确返回文件。您需要重新显示错误
.catch(function(e) {
console.log(e); // calling it as a method, btw
throw e;
})
在添加.catch(console.log)
之前,您还可以尝试使用或返回链中的承诺
此外,您正在使用,而实际上不应该使用。只要使用你已经拥有的承诺!您似乎想这样做:
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!
);
提供请求([])
将返回[]
并回调
愉快地接受[]
,然后声明()
应简化如下:
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
用于应使用窗口的条件。导出
我可能做了一两个非自愿的假设,但我相信类似于上述的东西应该能起作用
就我个人而言,我会处理回电话中的任何错误
declare(name, dependency_list, callback).then(handleSucces).then(null, handleError);
通过在单独的
中处理成功和失败,那么handleSuccess中抛出的任何未捕获错误也将被handleError
捕获,我猜您最初想做的是新承诺(函数(解析,拒绝){…捕获(拒绝);}
然而,这是一个反模式:-/感谢反模式示例。关于抛出的一个问题:我似乎在抛出,但我在其他地方捕捉到了错误。请参见上面的编辑。是的,对,在使用Promise
构造函数的原始代码中,这是一个未经处理的拒绝,因为该承诺不会发生任何事情。您需要调用拒绝(e)
而不是抛出。但是,在固定代码中,被拒绝的承诺被分配给回调dict
,当该承诺是请求()
ed。或者它不是这样工作的吗?拒绝为我解决了这个问题。我不确定我是否理解这个代码段,因为我为每个正在加载的文件设置了一个新的承诺。如果在承诺得到解决之前加载了文件,并且返回值被返回(在clapjs.callback\u dict[name]
)。如果它需要加载并且没有依赖项,我可以立即将新承诺设置为已解决。如果它有依赖项,则需要首先加载这些承诺,并将其包含在最终解决中。因此,我不明白为什么我可以在没有“新建”的情况下执行此操作承诺。是的,您通常会希望在某个地方创建一个新承诺
,通常用于加载文件。但不是在这个地方,您可以在没有依赖项的情况下创建一个已履行的承诺(Promise.resolve()
),也可以只编写一个请求()的承诺
通过调用.then()
返回到一个新的构造函数。不要在此处使用Promise
构造函数!重试(参见上面的edit2),但我没有得到好的结果,因为一些请求的模块返回了未定义的,,而使用我的原始代码总是返回正确的模块。我现在很好,如果有时间,我会调查并发布完整的示例,如果你想再次尝试。谢谢!
declare(name, dependency_list, callback).then(handleSucces).then(null, handleError);