javascript - 加载文件后如何将 promise 错误传播到更高的 promise 级别?

标签 javascript asynchronous error-handling promise bluebird

我正在使用 bluebird 开发异步脚本加载器我正在努力将错误传递到我可以捕获它的地方。

加载文件后,我将调用名为 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);
      });
  };

这一切都很好,除了我不希望此时有 catch 语句,因为错误处理应该在不同的模块中完成(console.log 只是一个标志)。

问题:
我如何将我的 declare 方法中发生的错误传播到更高的 promise 链?我曾希望在我的 declare 调用上添加一个 catch 处理程序会有所帮助,但这会破坏整个脚本 - 我假设是因为我从我的 declare 调用返回模块而不是有效的 promise 响应。

感谢任何提示!

编辑:
我正在调用声明:

 request([{"name": "foo", "src": "path/to/foo.js"}])
   .spread(foo) {

 })
 .catch(function (e) {
   console.log(e);
 })

request 将在 promise 中加载文件,该 promise 在加载文件时得到解析,并将文件内容作为回调运行,然后调用上述 declare 方法。不知何故,我的错误在途中丢失了(代码 here )。让我们看看我是否可以在某处捕获它...

编辑 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 相比,文件加载后会正确返回文件。

最佳答案

您需要重新抛出错误!

.catch(function(e) {
  console.log(e); // calling it as a method, btw
  throw e;
})

您也可以尝试使用 tap ,或者在添加 .catch(console.log) 之前返回链中的 promise 。


此外,您正在使用 manually-construct-promise antipattern ,虽然你实际上永远不需要 call the Promise constructor .只需使用您已经拥有的 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!
);

关于javascript - 加载文件后如何将 promise 错误传播到更高的 promise 级别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25372160/

相关文章:

javascript - 为什么这个 fiddle 不起作用?

javascript - 干净的代码和嵌套的 promise

c# - 如何在 C# 中将元素异步添加到 Queue<T>?

python - 如何错误检查pyppeteer page.goBack()

javascript - 在 javascript 代码中包含 .json 数据 (d3.js)

javascript - 从标签比较中获取 json id

javascript - 在 Node.js 中使用异步模块的问题

exception - 在我自己的异常类中获取异常行

powershell - 执行命令时如何忽略PowerShell中的特定错误?

javascript - 当可拖动框的js文件包含在php中时,它会丢失可拖动属性