Page 1 of 1

Promise.then1

Posted: Sun Jan 13, 2019 4:40 pm
by TIV73
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?

Re: Promise.then1

Posted: Mon Jan 14, 2019 2:30 am
by PetrCBR
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.

Re: Promise.then1

Posted: Tue Jan 15, 2019 5:10 pm
by TIV73
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

Re: Promise.then1

Posted: Wed Jan 16, 2019 6:48 am
by PetrCBR
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);
    }
});

Re: Promise.then1

Posted: Wed Jan 16, 2019 2:30 pm
by TIV73
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!