Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reconcile Future/Promise #27315

Open
jmesserly opened this issue Sep 13, 2016 · 11 comments
Open

reconcile Future/Promise #27315

jmesserly opened this issue Sep 13, 2016 · 11 comments
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. dev-compiler-async P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug web-dev-compiler

Comments

@jmesserly
Copy link

From @jmesserly on June 25, 2015 20:50

For JS interop, it would be ideal if we could adapt Dart Futures to implement the Promise interface.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

This will also ease DOM interop as Promise becomes more common.

Ideally, Dart Future actually is a JS Promise, simply exposing different user-facing APIs (similar to Dart builtin List type and JS Array). But we could also try adapters, similar to Dart Iterable objects exposing a [Symbol.iterator]() method to JS, and Dart for-each consuming JS Iterables.

Copied from original issue: dart-archive/dev_compiler#245

@jmesserly
Copy link
Author

related #221

@jmesserly
Copy link
Author

From @jacob314 on January 4, 2016 19:10

This is now becoming an issue for JS interop

@jmesserly
Copy link
Author

yeah, just wanted to add an update: this is something we're definitely doing, only question is when it happens. Probably after we've gotten the Dart language tests and modular compilation in a good place.

@jmesserly
Copy link
Author

and SDK issue is #24679

@rayk
Copy link

rayk commented Jan 16, 2017

This issue has been hanging around for almost a year.

Actually I first hit it here. From my understanding there has not been any work on this. I know that @alan-knight was playing some Service worker stuff (using all dart:html), but look at the repo it looks like it did not move forward, possibly because the register required handling the promise.

If my assumptions above are correct?

Then certainly this needs to addressed in a once and for all, promises are spreading in JS and have it map one to one with a Future in the dart2JS is reasonable. Otherwise there will be just be promise completer boilerplate all over the place.

There is a type definition for es6 promises yet JS Facade Gen does not appear to handle it too well @jacob314.

Hence I for one would like to this issue given some priority and clarity.

@jmesserly jmesserly added the P2 A bug or feature request we're likely to work on label Feb 18, 2017
@jmesserly jmesserly self-assigned this Feb 18, 2017
@jmesserly
Copy link
Author

jmesserly commented Feb 18, 2017

Hit this via #28422.

I'm going to see if we can do adapters in both directions:

  • create a _PromiseFuture internal type that maps to native JS Promise, but implements Dart's Future interface.
  • inject a compatible "then" and "catch" method onto Dart Futures, essentially so they implement the Promise interface.

Tricky part here is figuring out how to inject "then" and "catch" because those aren't symbolized and collide with the Dart names. Then again ... once the Future interface is marked as "may be native" we might get the renaming for free.

EDIT: ah, because JavaScript Promise recognizes the mere existence of "then", we may need to use "dartx.then" on all Dart objects, kinda similar to "toString", so it doesn't pick up accidentally and be treated as a Promise "then".

@jmesserly jmesserly removed their assignment May 5, 2017
@daniel-v
Copy link

Would be nice to have this.

@lexaknyazev
Copy link
Contributor

If/when dart compilers get native support of JS Promises, please don't tie it to dart:html.

FWIW, we're using the following boilerplate which works mostly fine both in browsers and node:

@JS()
class Promise<T> {
  external Promise(void executor(void resolve(T result), Function reject));
  external Promise then(void onFulfilled(T result), [Function onRejected]);
}

To create a Promise from Future (to send it to JS world):

return new Promise<MyType>(allowInterop((resolve, reject) {
  myFuture.then(resolve, onError: reject);
}));

To create a Future from Promise (gotten from JS world):

final completer = new Completer<MyType>();
myPromise.then(allowInterop(completer.complete),
    allowInterop(completer.completeError));
return completer.future;

@munificent munificent added type-enhancement A request for a change that isn't a bug and removed js-interop labels Jun 21, 2018
@vsmenon vsmenon added the area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. label Jul 20, 2019
@Sunbreak
Copy link

Sunbreak commented Dec 14, 2019

If/when dart compilers get native support of JS Promises, please don't tie it to dart:html.

FWIW, we're using the following boilerplate which works mostly fine both in browsers and node:

@JS()
class Promise<T> {
  external Promise(void executor(void resolve(T result), Function reject));
  external Promise then(void onFulfilled(T result), [Function onRejected]);
}

To create a Promise from Future (to send it to JS world):

return new Promise<MyType>(allowInterop((resolve, reject) {
  myFuture.then(resolve, onError: reject);
}));

To create a Future from Promise (gotten from JS world):

final completer = new Completer<MyType>();
myPromise.then(allowInterop(completer.complete),
    allowInterop(completer.completeError));
return completer.future;

flutter/flutter#46973

Flutter for Web is beta now. The Promise implementation seems to work in debug mode but not profile/release mode.
@lexaknyazev Could you show some light on me?

@Sunbreak
Copy link

Sunbreak commented Dec 14, 2019

It is promising!

/// Converts a JavaScript Promise to a Dart [Future].
///
/// ```dart
/// @JS()
/// external Promise<num> get threePromise; // Resolves to 3
///
/// final Future<num> threeFuture = promiseToFuture(threePromise);
///
/// final three = await threeFuture; // == 3
/// ```
Future<T> promiseToFuture<T>(jsPromise) {
final completer = Completer<T>();
final success = convertDartClosureToJS((r) => completer.complete(r), 1);
final error = convertDartClosureToJS((e) => completer.completeError(e), 1);
JS('', '#.then(#, #)', jsPromise, success, error);
return completer.future;
}

@jodinathan
Copy link

any news on this?

would be awesome to be able to await a promise without having to use promiseToFuture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. dev-compiler-async P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug web-dev-compiler
Projects
None yet
Development

No branches or pull requests

9 participants