如何在Promise链中从THREE.js加载器的回调获取返回值
把Three.js回调式加载器整合进Promise链的方案
嘿,我来帮你理清楚怎么把Three.js那些单值回调的加载器无缝接入你的Promise调用链里,顺便也把你提到的Bluebird .asCallback的疑惑给你解开~
一、原生Promise封装法(不用Bluebird也能搞定)
Three.js的加载器大多是回调风格的,咱们先把它包装成返回Promise的函数,这样就能直接放进你的Promise链里了。举个GLTFLoader的例子:
// 封装加载器为Promise函数 function load3DModel(url) { return new Promise((resolve, reject) => { const loader = new THREE.GLTFLoader(); loader.load( url, (loadedResult) => resolve(loadedResult), // 成功时把结果传入Promise链 undefined, // 进度回调可按需添加,这里暂时留空 (loadError) => reject(loadError) // 错误也要传给Promise的catch ); }); } // 延续你的现有Promise链 yourExistingPromise .then((previousStepResult) => { // 用上一步的结果做逻辑,比如拿到要加载的模型URL const targetModelUrl = previousStepResult.modelUrl; // 返回封装好的加载Promise,链会自动延续 return load3DModel(targetModelUrl); }) .then((newResult) => { // 这里就能拿到加载器返回的newResult啦! console.log('模型加载完成:', newResult); // 继续你的后续业务逻辑 }) .catch((error) => { // 统一处理整个链里的错误(包括上一步和加载过程的错误) console.error('Promise链出错:', error); });
这个方法很直观,原生JS就能实现,不需要额外依赖。
二、Bluebird的正确打开方式
如果你已经在用Bluebird,其实用promisify或者promisifyAll来转换加载器方法会更省事,而不是.asCallback——这里可能你对.asCallback的用法有点误解,我给你说清楚:
1. 用promisify转加载器方法
const Bluebird = require('bluebird'); // 把GLTFLoader的load方法转成返回Bluebird Promise的函数 const loadModel = Bluebird.promisify(new THREE.GLTFLoader().load, { context: new THREE.GLTFLoader() // 绑定上下文,避免this指向问题 }); // 同样延续你的Promise链 yourExistingPromise .then((prevResult) => loadModel(prevResult.modelUrl)) .then((newResult) => { // 处理加载后的newResult }) .catch((err) => { /* 错误处理 */ });
2. 关于.asCallback的真实用途
.asCallback不是用来延续Promise链的,它的作用是把Promise风格的接口转换成传统的回调风格。比如你有一个Promise,但需要传给只接受(err, result)回调的函数时,才会用到它:
yourExistingPromise .then((prevResult) => loadModel(prevResult.modelUrl)) // 用asCallback把Promise转换成回调接口 .asCallback((err, newResult) => { if (err) { console.error('加载失败:', err); return; } // 这里用回调方式处理newResult console.log('加载结果:', newResult); });
如果你只是想延续Promise链继续用.then,完全不需要.asCallback,直接返回Promise就行。
总结一下
不管用原生Promise还是Bluebird,核心思路都是把回调式的加载器包装成Promise,然后在现有链的.then里返回这个Promise,就能自动把加载器的newResult传到下一个.then里。.asCallback是适配回调场景的工具,不是延续Promise链的必需品~
内容的提问来源于stack exchange,提问作者jrose
相关产品推荐
相关产品推荐

