我们有两个打字稿课。在它们上定义一个方法作为对象参数,然后在另一个类中进行传输。
class MyService {
public options: { [key: string]: any };
constructor() { }
public upload(file: File): void {
const parallelHasher = new ParallelHasher('/public/md5_worker.js');
this.options = {
concurrency: 1,
autoUpload: true,
hashMethod: parallelHasher.hash // HERE
};
const uploadService = new UploadService(this.options);
this.uploadsProgress = uploadService.start(file)
}
}
class UploadService {
constructor(public options: any) { }
public async start(file: File): Promise<void> {
const hash = await this.options.hashMethod(file);
this.proceed(file, hash);
}
public proceed(file: File, hash: string): void {
// do something
}
}
由于第三方的哈希方法,在调用UploadService.start()
时遇到错误:
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'push' of undefined
TypeError: Cannot read property 'push' of undefined
at parallel_hasher.js:25
以下是第三方代码中的相关部分:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ParallelHasher = (function () {
function ParallelHasher(workerUri) {
this._queue = [];
this._ready = true;
var self = this;
if (Worker) {
self._hashWorker = new Worker(workerUri);
self._hashWorker.onmessage = self._recievedMessage.bind(self);
self._hashWorker.onerror = function (err) {
self._ready = false;
console.error('Hash worker failure', err);
};
}
else {
self._ready = false;
console.error('Web Workers are not supported in this browser');
}
}
ParallelHasher.prototype.hash = function (blob) {
var self = this;
var promise;
promise = new Promise(function (resolve, reject) {
self._queue.push({
blob: blob,
resolve: resolve,
reject: reject,
});
self._processNext();
});
return promise;
};
return ParallelHasher;
}());
exports.ParallelHasher = ParallelHasher;
如您所见,_queue
是在构造函数中定义的,并且在hash()
方法尝试使用它来将新元素推入队列时应该存在。
通过在第三方的var self = this;
方法中将调试器与hash
放置在一起,this
的值等效于this.options
类中的MyService
,而不是ParallelHasher
:
concurrency: 1,
autoUpload: true,
hashMethod: parallelHasher.hash
实际上,选项中没有_queue
,因此会出现错误。
以某种方式,不是在ParallelHasher
实例中而是在options
对象中设置了第三方方法调用的上下文。
我不太了解为什么以及如何防止这种情况发生。
答案 0 :(得分:2)
库的parallelHasher.hash
方法未绑定到this
,因此当您传递方法本身时,它将丢失其this
指针。相反,您可以在选项中创建一个匿名函数,以使库方法保持其this
上下文,而无需修改库本身。
this.options = {
concurrency: 1,
autoUpload: true,
hashMethod: (blob) => {
return parallelHasher.hash(blob);
}
};
以下一些文档值得阅读,以更好地了解正在发生的事情:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind