Angular集成ml5与p5时遇TypeError: objectDetector.detect不是函数
问题:Angular集成ml5+p5时出现
TypeError: this.objectDetector.detect is not a function 遇到的错误:
TypeError: this.objectDetector.detect is not a function
控制台打印objectDetector结果:
ZoneAwarePromise {__zone_symbol__state: null, __zone_symbol__value: Array(0)}
p5绘图功能正常,但ml5无法正常工作,组件代码如下:
import { Component, OnInit } from '@angular/core'; import * as p5 from 'p5'; declare let ml5: any; @Component({ selector: 'app-new-found', templateUrl: './new-found.component.html', styleUrls: ['./new-found.component.scss'] }) export class NewFoundComponent implements OnInit { objectDetector; img; constructor( ) { } ngOnInit(): void { const sketch = (s) => { s.preload = () => { this.objectDetector = ml5.objectDetector('cocossd'); console.log('detector object is loaded', this.objectDetector); this.img = s.loadImage('https://i.imgur.com/Mzh4cHR.jpg'); } s.setup = () => { s.createCanvas(700, 700).parent('test-canvas'); this.objectDetector.detect(this.img, this.gotResult); s.image(this.img, 0, 0); }; s.draw = () => { }; } let canvas = new p5(sketch); } gotResult(error, results) { if (error) { console.error(error); } else { console.log(results); //drawResults(results); } } }
ml5库已在index.html的<HEAD>标签中引入,求解决方法。
解决方法
核心原因
ml5.objectDetector('cocossd')返回的是一个Promise对象,而非直接的检测器实例。你直接将Promise赋值给this.objectDetector,调用detect方法自然会报错——Promise没有这个方法。
修正步骤
- 等待Promise完成获取检测器实例:利用p5的
preload支持异步操作的特性,在preload中等待Promise resolve后再赋值给this.objectDetector。 - 修复回调函数的
this指向:gotResult作为回调时,默认this不是组件实例,需要绑定或者改用箭头函数确保上下文正确。
修改后的代码
import { Component, OnInit } from '@angular/core'; import * as p5 from 'p5'; declare let ml5: any; @Component({ selector: 'app-new-found', templateUrl: './new-found.component.html', styleUrls: ['./new-found.component.scss'] }) export class NewFoundComponent implements OnInit { objectDetector; img; constructor() { } ngOnInit(): void { const sketch = (s) => { // 改用async函数处理异步加载 s.preload = async () => { // 等待Promise resolve获取检测器实例 this.objectDetector = await ml5.objectDetector('cocossd'); console.log('detector object is loaded', this.objectDetector); this.img = s.loadImage('https://i.imgur.com/Mzh4cHR.jpg'); } s.setup = () => { s.createCanvas(700, 700).parent('test-canvas'); // 调用detect时,用箭头函数绑定this,确保gotResult能访问组件上下文 this.objectDetector.detect(this.img, (error, results) => this.gotResult(error, results)); s.image(this.img, 0, 0); }; s.draw = () => {}; } new p5(sketch); } gotResult(error, results) { if (error) { console.error(error); } else { console.log(results); // 这里可以添加绘制检测结果的逻辑 } } }
补充说明
- p5的
preload会等待所有异步操作完成后才进入setup,所以用async/await不会导致setup提前执行。 - 如果不想用
async/await,也可以用.then()写法:s.preload = () => { ml5.objectDetector('cocossd') .then(detector => { this.objectDetector = detector; console.log('detector object is loaded', this.objectDetector); }); this.img = s.loadImage('https://i.imgur.com/Mzh4cHR.jpg'); }
内容的提问来源于stack exchange,提问作者Michał B
相关产品推荐
相关产品推荐

