使用jQuery.YoutubeBackground.js添加Promise时遇promise.then不是函数错误求助
Hey there, let's break down why you're hitting this Promise error and how to fix it—especially since you suspect the if (promise !== undefined) check is part of the problem.
What's Causing the Error?
The promise.then is not a function message means whatever you're calling .then() on isn't a valid Promise instance. This usually happens in one of a few ways with this plugin:
- You're trying to use
.then()on the plugin's default return value (a jQuery object), which doesn't natively have a Promise attached. - Your
if (promise !== undefined)check runs before the Promise is actually initialized, sopromiseis stillundefinedor a non-Promise value when you try to use it. - You haven't properly wrapped the plugin's asynchronous video-loading logic into a Promise.
How to Fix It (Step-by-Step)
1. Wrap Plugin Initialization in a Promise (No Source Code Changes)
If you don't want to modify the plugin's core code, create a wrapper function that ties a Promise to the plugin's built-in ready/error callbacks:
function loadYoutubeBackground(elementSelector, options) { return new Promise((resolve, reject) => { // Extend options to include Promise resolution logic const extendedOptions = { ...options, onReady: function() { resolve("YouTube background video loaded successfully"); // Call original onReady callback if provided if (options.onReady) options.onReady(); }, onError: function() { reject(new Error("Failed to load YouTube background video")); // Call original onError callback if provided if (options.onError) options.onError(); } }; // Initialize the plugin $(elementSelector).youtube_background(extendedOptions); }); } // Usage example loadYoutubeBackground("#hero-section", { videoId: "dQw4w9WgXcQ", mute: true }) .then((message) => { console.log(message); // Run your post-load logic here (e.g., show page content) }) .catch((error) => { console.error(error); // Fallback logic (e.g., show a static background image) });
2. Modify the Plugin Source to Return a Promise
If you want to add native Promise support to the plugin, adjust the source code to create and expose a Promise correctly—ensure your if (promise !== undefined) check lives in the right scope:
// Inside the plugin's main function $.fn.youtube_background = function(options) { const $this = this; // Initialize Promise at the start of plugin logic const promise = new Promise((resolve, reject) => { // ... keep all original plugin initialization code ... // Resolve Promise when video is ready (hook into existing onPlayerReady logic) function onPlayerReady(event) { // ... original onReady logic ... resolve($this); // Resolve with the jQuery element for chaining } // Reject Promise on video load failure function onPlayerError(event) { // ... original error logic ... reject(new Error("YouTube video failed to load")); } }); // Attach Promise to the jQuery object for external access $this.promise = promise; // Maintain the plugin's original chainability return $this; }; // Usage example $("#hero-section").youtube_background({ videoId: "dQw4w9WgXcQ", mute: true }) .promise.then((element) => { console.log("Video ready on element:", element); // Your post-load code here }) .catch((error) => { console.error(error); });
3. Fix the if (promise !== undefined) Check
If your existing code includes this check, make sure it runs after the Promise is initialized, and use a more reliable validation:
// ❌ Wrong: Checking before Promise is created if (promise !== undefined) { promise.then(...); } const promise = new Promise(...); // ✅ Correct: Check after Promise is initialized const promise = new Promise(...); if (promise instanceof Promise) { // Better than just checking undefined promise.then(...); }
Checking promise instanceof Promise ensures you're working with a valid Promise instance, not just any non-undefined value.
Key Takeaways
- Always confirm you're calling
.then()on a real Promise instance. - Tie Promise resolution/rejection directly to the plugin's existing ready/error events.
- If modifying the plugin source, expose the Promise on the returned jQuery object for easy access.
内容的提问来源于stack exchange,提问作者Tortai

