Jump to content

ecma.promise


Recommended Posts

  • Moderators

a simple promise in vanilla javascript looks something like this

var promise1 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo');
  }, 300);
});

promise1.then(function(value) {
  console.log(value);
  // expected output: "foo"
});

console.log(promise1);
// expected output: [object Promise]

 

Using the Ecma.promise unit the next code snippet does compile, but fails on execution ("reference error, PromiseInit is not defined")

  var Pinit := new JPromiseInit;

  var p := JPromise.Create(PInit);

  p.then(function(x:variant):variant
    begin
      result := x;
    end);

Googling 'PromiseInit' or "_Promise" only gives a handful of vague (and dated) references

Nonplussed

Link to post
Share on other sites
  • Administrators

I read a bit about this. Your JS example works and as promises do work natively now in JS, I think that ECMA.Promise is outdated (or never worked in the first place).

It's a better idea for us to write a new class to the RTL to handle promises. Do you have any suggestions on what you'd look for in a class to make it easy to use?

Link to post
Share on other sites

The unit ECMA.Promise is broken. I use this definition Using Promises in SMS

unit uPromises;

interface

uses W3C.Console, W3C.DOM, W3C.XMLHttpRequest;

type
  TVariantDynArray = array of Variant;
  JDeferred = class;
  TJPromiseCallback = procedure(Value: Variant);
  TJDeferredObject_fn = function(d: TJPromiseCallback): Variant;
  TJDeferredObject = procedure(resolve: TJPromiseCallback; reject: TJPromiseCallback);
  TJPromiseCallback_fn = function(Value: Variant): Variant;
  TJDeferredEventHandler = function(event: Variant): Variant;

  JPromise = class external 'Promise'
    constructor Create(fn: TJDeferredObject_fn { = nil}); overload;
    constructor Create(resolve: TJDeferredObject_fn; reject: TJDeferredObject_fn); overload;
    constructor Create(fn: TJDeferredObject); overload;
    function always(alwaysCallbacks: TVariantDynArray): JPromise;
    function done(doneCallbacks: TVariantDynArray): JPromise; overload;
    function done(doneCallbacks: Variant): JPromise; overload;
    function fail(failCallbacks: TVariantDynArray): JPromise;
    function progress(progressCallbacks: TVariantDynArray): JPromise;
    function state(): string;
    function &then(doneCallbacks: Variant; failCallbacks: Variant{ = undefined};
      progressCallbacks: Variant { = undefined}): JPromise; external 'then';
    function &then(onFulfilled: TJPromiseCallback_fn = nil): JPromise; overload;
      external 'then';
    function &then(onFulfilled: TJPromiseCallback_fn; onRejected:
      TJPromiseCallback_fn): JPromise; overload; external 'then';
    function &then(onFulfilled: TJPromiseCallback; onRejected:
      TJPromiseCallback): JPromise; overload; external 'then';
    function catch(rejecTJPromiseCallback: Variant = nil): JPromise; overload;
    function catch(rejecTJPromiseCallback: TJPromiseCallback_fn): JPromise; overload;
    class function promise(target: Variant): JPromise;
  end;

type
  JDeferred = class external 'Promise'(JPromise)
    function notify(args: TVariantDynArray): JDeferred;
    function notifyWith(context: Variant; args: TVariantDynArray): JDeferred;
    function reject(args: TVariantDynArray): JDeferred; overload;
    function reject(args: Variant): JDeferred; overload;
    function reject(args: TJDeferredEventHandler): JDeferred; overload;
    function rejectWith(context: Variant; args: TVariantDynArray): JDeferred;
    function resolve(args: TVariantDynArray): JDeferred; overload;
    function resolve(value: Variant = nil): JPromise; overload;
    function resolveWith(context: Variant; args: TVariantDynArray): JDeferred;
    function all(iterable: TVariantDynArray): JPromise; overload;
    function race(iterable: TVariantDynArray): JPromise;
  end;

  { global external functions }
  function Promise : JDeferred; external 'Promise' property;
  function queue: JPromise; external 'Promise.resolve()';
  function Error(message: variant): variant; external 'Error';
  function document: variant; external "document" property;
  function window : Variant; external 'window' property;
  function &typeof(obj:variant): variant; overload; external "typeof";

  function wait(ms: Integer): JPromise;
  function getURI(url: string): Variant;
  function getFile(url: string): variant;
  //function myRequire(url: string): Variant;

implementation

function wait(ms: Integer): JPromise;
  function setTimeout(ahandler : TJPromiseCallback; aTimeout : Integer): Integer; external 'window.setTimeout';
begin
  result := JPromise.Create(
    procedure (resolve, reject: TJPromiseCallback)
    begin
      setTimeout(resolve, ms);
    end);
end;

function getURI(url: string): Variant;
var
  request: JXMLHttpRequest;

  procedure p(resolve: TJPromiseCallback; reject: TJPromiseCallback);
  // Standard XHR to load an image
    procedure doOnLoad;
    begin
      // This is called even on 404 etc
      // so check the status
      if (request.status = 200) then
      begin
       // If successful, resolve the promise by passing back the request response
       resolve(request.response);
      end
      else
      begin
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error('File didn''t load successfully; error code: ' + request.statusText));
      end;
    end;

    procedure doOnError;
    begin
      // Also deal with the case when the entire request fails to begin with
      // This is probably a network error, so reject the promise with an appropriate message
      reject(Error('There was a network error.'));
    end;

  Begin
    request := JXMLHttpRequest.Create;
    request.open('GET', url);

    // When the request loads, check whether it was successful
    request.addEventListener('load', @doOnLoad);
    // Handle network errors
    request.addEventListener('abort', @doOnError);
    // Send the request
    request.send();
  End;

begin
// Create new promise with the Promise() constructor;
// This has as its argument a function
// with two parameters, resolve and reject
  Result := JPromise.Create(@p);
end;

function getFile(url: string): variant;
begin
// Create new promise with the Promise() constructor;
// This has as its argument a function
// with two parameters, resolve and reject
Result := JPromise.create(
  procedure(resolve: TJPromiseCallback; reject: TJPromiseCallback)
  // Standard XHR to load an image
  var request: JXMLHttpRequest;
  begin
  request := new JXMLHttpRequest();
  request.open('GET', url);

  // When the request loads, check whether it was successful
  request.onload := lambda
  begin
    // This is called even on 404 etc
    // so check the status
    if (request.status = 200) then
    begin
     // If successful, resolve the promise by passing back the request response
     resolve(request.response);
    end
    else
    begin
      // Otherwise reject with the status text
      // which will hopefully be a meaningful error
      reject(Error("File didn't load successfully; error code: " + request.statusText));
    end;
  end;
  end;
  // Handle network errors
  request.onerror := lambda
    // Also deal with the case when the entire request fails to begin with
    // This is probably a network error, so reject the promise with an appropriate message
    reject(Error('There was a network error.'));
  end;
  // Send the request
  request.send();
end);
end;


/*
function myRequire( url: string): Variant;
  function ev(win: Variant; arr: array of Variant): Variant; external 'eval.apply';
  var
    ajax: JXMLHttpRequest;

  function onReady(event: JEvent): Variant;
  var
    script: Variant;
  begin
    script := ajax.response; // ?? ajax.responseText;
    if (ajax.readyState = 4) then begin
      case( (ajax.status)) of
      200: begin
        //eval.apply( window, [script] );
        ev( window, [script] );
        console.log('script loaded: '+ url);
      end else
        console.log('ERROR: script not loaded: '+ url);
      end;
    end;
  end;

begin
  ajax := JXMLHttpRequest.Create;
  ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
  ajax.onreadystatechange := @onReady;
  ajax.send(null);
end;*/

end.

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...