如何在加载文件后将承诺错误传播到更高的承诺级别



我正在使用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捕获。

最新更新