Promise.then1

To discuss development of addons / skins / customization of MediaMonkey.

Moderator: jiri

TIV73
Posts: 94
Joined: Sat Nov 12, 2011 1:31 pm

Promise.then1

Post by TIV73 » Sun Jan 13, 2019 4:40 pm

Hi there,
I noticed that promise.js contains a custom implementation of the promise prototype which contains a then1 method. It looks like it is shorthand to call the regular then method with one instead of two parameters - is this intended for flow control to allow functions to continue in case a promise fails?
In general, are there any best practices on when and how to use then1 vs then?

Besides that, it seems like the custom function breaks the default js async functionality, e.g. I just stumbled over that issue when using the autotag framework. getArtwork is called by applyToTracks in searchCommon.js and the returned promise is then resolved via then1.
The getArtwork function in the same file looks like this

Code: Select all

getArtwork: function (searchManager, founds, list) {
	return new Promise(function (resolve, reject) {
		resolve(false);
	});
},
I have a custom autotagger which makes heavy use of async/await and overrides the getArtwork function. So it looks more like this

Code: Select all

getArtwork: async function (searchManager, founds, list) {
	[some magic here]
	return true // or false, depending on the success of the lookup
}
I guess I could rewrite getArtwork to use promises instead, or override applyToTrack to make it inline with the rest of the tagger, but both options feel like workarounds.

Any pointers on how I could work with this issue?

PetrCBR
Posts: 1597
Joined: Tue Mar 07, 2006 5:31 pm
Location: Czech
Contact:

Re: Promise.then1

Post by PetrCBR » Mon Jan 14, 2019 2:30 am

As you already know, then1 uses just one parameter, but internally it is call then with same function for resolve and reject. This method can be used when you need to handle both (success and fail) with same method. It shouldn't break any promise functionality, but will check.

TIV73
Posts: 94
Joined: Sat Nov 12, 2011 1:31 pm

Re: Promise.then1

Post by TIV73 » Tue Jan 15, 2019 5:10 pm

To clarify - everything with the custom promise.js works fine except for the combination of async/await with then1. I did a quick test:

Code: Select all

 PromiseFunction1: function(){
    return new Promise((resolve, reject) => resolve("promise1"));
  },

  PromiseFunction2: function(){
    return new Promise((resolve) => resolve("promise2"));
  },

  AsyncFunction: async function(){
    return "async";
  },

  Caller: function(){
    this.PromiseFunction1().then(result => console.log(result)); // ok
    this.PromiseFunction2().then(result => console.log(result)); // ok
    this.AsyncFunction().then(result => console.log(result)); // ok

    this.PromiseFunction1().then1(result => console.log(result)); // ok
    this.PromiseFunction2().then1(result => console.log(result)); // ok
    this.AsyncFunction().then1(result => console.log(result)); // this.AsyncFunction(...).then1 is not a function
  },

  CallerAsync: async function(){
    this.PromiseFunction1().then(result => console.log(result)); // ok
    this.PromiseFunction2().then(result => console.log(result)); // ok
    this.AsyncFunction().then(result => console.log(result)); // ok

    this.PromiseFunction1().then1(result => console.log(result)); // ok
    this.PromiseFunction2().then1(result => console.log(result)); // ok
    this.AsyncFunction().then1(result => console.log(result)); // this.AsyncFunction(...).then1 is not a function

    console.log(await this.PromiseFunction1()); // ok
    console.log(await this.PromiseFunction2()); // ok
    console.log(await this.AsyncFunction()); // ok
  }
My wild guess on why this is happening - whenever a promise is created explicitly, it is done so with the custom promise.js and everything works. Async functions wrap their return value in a promise as well, but since it's done implicitly, the function defaults back to the built-in promise type, not the custom one.

Image

PetrCBR
Posts: 1597
Joined: Tue Mar 07, 2006 5:31 pm
Location: Czech
Contact:

Re: Promise.then1

Post by PetrCBR » Wed Jan 16, 2019 6:48 am

Yes it is possible as we're not using built-in promises (we need to handle promises somehow in native code as well and built-in promises doesn't allow that).
Can you try to add this code at the beginning of mminit.js (as this script is always loaded at the beginning and promise.js is loaded later):

Code: Select all

Object.defineProperty(Promise.prototype, 'then1', {
    enumerable: false,
    value: function (method) {
        return this.then(method, method);
    }
});

TIV73
Posts: 94
Joined: Sat Nov 12, 2011 1:31 pm

Re: Promise.then1

Post by TIV73 » Wed Jan 16, 2019 2:30 pm

Yup, appending a new function property to the promise prototype in mminit solves the issue. With that I can't reproduce the issue anymore. Thanks a lot!

Post Reply