Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Proxy a Promise in JavaScript es6

I'm trying to Proxy a Promise in native Firefox (and using Babel).

var prom = new Promise(function(resolve, reject){resolve(42)});
var promProxy = new Proxy(prom, {});
promProxy.then(function(response){console.log(response)});

This doesn't work, I get 'TypeError: 'then' called on an object that does not implement interface Promise.'

like image 630
sam Avatar asked Jun 13 '15 13:06

sam


People also ask

What is proxy in ES6?

ES6 proxies sit between your code and an object. A proxy allows you to perform meta-programming operations such as intercepting a call to inspect or change an object's property. The following terminology is used in relation to ES6 proxies: target. The original object the proxy will virtualize.

Is Promise a proxy?

A Promise is a proxy for a value that has not been computed yet. It allows a process to run side-by-side or asynchronously on the premise that upon completion, would return an immutable value or an error. A pending Promise can be resolved with a value or rejected with an error.

How do I invoke a Promise in JavaScript?

You can create a promise using the promise constructor like this: let promise = new Promise(function(resolve, reject) { // Make an asynchronous call and either resolve or reject }); In most cases, a promise may be used for an asynchronous operation.


2 Answers

You need to have your handler implement the get() trap and return the bound version of prom.then

var prom = new Promise(function(resolve, reject){resolve(42)});
var promProxy = new Proxy(prom, {
  get: function(target, prop) {
    if (prop === 'then') {
      return target.then.bind(target);
    }
  }
});
promProxy.then(function(response){console.log(response)});

Note that if you simply want to proxy all accessors, the get function would look like this:

var promProxy = new Proxy(prom, {
  get: function(target, prop) {
    var value = target[prop];
    return typeof value == 'function' ? value.bind(target) : value;
  }
});

bind will ensure the function won't be incorrectly called when you're dealing with Native objects such as Promises, or the console.

EDIT: In some instances browsers / node will have an outdated version of Proxies, in which case you'll want to use harmony-reflect to bring it up to date.

like image 166
Travis Kaufman Avatar answered Oct 11 '22 05:10

Travis Kaufman


Hmm, this question is How to Proxy a Promise. I arrived here looking for How to Promise a Proxy -- or maybe more precisely, How to resolve a Proxy. I suspect others may land here, too, so I'll post this here, just in case.

I already have a nice working proxy object, and then I go and try to wrap it in a promise:

var p = new Promise(function(resolve, reject) {
  var proxy = get_my_proxy();
  resolve(proxy);
});

And wouldn't you know it, then darn resolve method asks my proxy for a then property (which is unexpected by my proxy logic, causing it to throw). It may not be ideal, depending on what your proxy is for, but here's how I worked around this (and appropriately enough, as my question is the inverse of this one, my solution is the inverse as well) -- by returning null for then -- thereby letting resolve() know that I didn't pass it a Promise (aka Thenable).

get: function(target, prop) {
  if (prop === 'then') return null; // I'm not a Thenable
  // ...the rest of my logic
}
like image 24
Jeff Ward Avatar answered Oct 11 '22 07:10

Jeff Ward