是否可以检索 Promise 实例的实现细节?让我们假设以下创建的承诺...
let myPromise = new Promise(function (success, error) {
/* implementation */
}
人们能否以某种方式访问匿名函数......
function (success, error) {
/* implementation */
}
...或者获取代码文件中匿名函数的位置?
不。 Promise 对象不包含代码,既不能在内部使用,也不能被 JavaScript 访问。 Promise 代表任务的“结果”,而不是任务本身,它“不可运行”。该功能仅在构建期间使用。 出于演示目的,下一个提供的示例代码尽可能扩展了覆盖和包装内省方法。
使用其自身的代理版本重新分配
Promise
[[Construct]]
插槽的调用由自定义代码处理。
将拦截自定义代码包裹在Promise
executor
函数中。
将拦截自定义代码包裹在executor
resolve
函数中。
访问Proxy
executer
函数并记录它,以及访问传递给
resolve
函数的参数可能会揭示一些 executer
函数的实现细节,从而可能能够提供有关下一步深入研究的一些提示。
// - The actual use case, an asynchronously implemented
// `wait` functions which resolves after the provided
// amount of milliseconds.
// - It uses the proxied version of the before created
// and reassigned global `Proxy` constructor function.
async function waitForResolvedData(valueInMSec) {
console.log('... executing ...\n\n');
return new Promise(resolve =>
setTimeout(resolve, valueInMSec, { foo: 'Foo', bar: 'Bar'})
);
}
(async () => {
console.log('waiting ...');
const data = await waitForResolvedData(3000);
console.log('\n... awaited data ...', data);
})();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
// - reassign the `Promise` constructor function
// with a proxied version of itself, where the
// invocation of its internal `[[Construct]]`
// slot gets handled.
window.Promise = (Promise => {
const handlers = {
construct(target, [executor]) {
console.log(
`\`${ target.name }\` creation with following \`executer\` function ...\n`, executor
);
// - wrap intercepting custom code around the
// `Promise` constructor's `executor` function.
executor = (proceed => {
return ((/*resolve, reject*/...args) => {
let [ resolve, reject ] = args;
// - wrap intercepting custom code around the
// `executor` function's `resolve` function.
resolve = (proceed => {
return ((...args) => {
console.log('`\nresolve` function intercepted with following args ...\n', args);
console.log('original `resolve` function ...\n', proceed);
proceed(...args);
});
})(resolve);
console.log('`executor` intercepted with following args ...\n', args);
console.log('original `executor` function ...\n', proceed);
proceed(resolve, reject);
});
})(executor);
return new target(executor);
},
};
return new Proxy(Promise, handlers);
})(window.Promise);
</script>