0

here is a code example:

var promise = new Promise((resolve, reject) => {
  resolve("resolved");
});


promise.abort = function () {
  console.log("abort!");
};

console.log(promise.abort());

function bar() {
  return promise.then((value) => {
    return value + "!";
  });
}

newPromise = bar();
newPromise.then(value => {
  console.log(value);
})


console.log(newPromise.abort());

i added a custom function to a promise. call the function abort() works like expected. in the function bar() i use the then() method to log out the resolved value. i know that the return value of bar() is a new promise. but it loses the custom function abort().

how can i inheritance the custom function to the new promise?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
JuKe
  • 663
  • 2
  • 7
  • 20
  • 2
    A promise should not have a method for aborting it. Put it somewhere separate, and call that function directly - not on the promise, and definitely not on descendant promises. What would you expect `promise.then(_ => timeout(500)).abort()` to do? – Bergi Jul 09 '21 at 23:18

2 Answers2

2

Create your own class and subclass the native Promise. Then you can keep custom methods as .then() will return the custom class

class MyPromise extends Promise {
  abort() {
    console.log("abort!");
  }
}

var promise = new MyPromise((resolve, reject) => {
  resolve("resolved");
});

console.log(promise.abort());

function bar() {
  return promise.then((value) => {
    console.log(value);
  });
}

newPromise = bar();

console.log(newPromise.abort());
VLAZ
  • 26,331
  • 9
  • 49
  • 67
  • is there an old fashion way without `extend`? – JuKe Jul 09 '21 at 22:28
  • The "old fashioned way" would probably be to implement your own promise from scratch, instead of simply extending an existing one. See [How is a promise/defer library implemented?](https://stackoverflow.com/q/17718673), [Concept - Distilling how a promise works?](https://stackoverflow.com/q/15668075), and [Basic Javascript promise implementation attempt](https://stackoverflow.com/q/23772801) for pointers. But I wouldn't recommend it. Using `extend` is the correct way to add behaviour to built-ins. – VLAZ Jul 09 '21 at 22:35
  • 1
    @JuKe It is impossible to (properly) subclass (ES6) builtins like `Promise` without ES6 `class` syntax – Bergi Jul 09 '21 at 23:19
1

You cannot cancel/abort a Promise. One approach is to write a generic timeout or similar function to handle a long withstanding Promise -

function sleep(ms) {
  return new Promise(r => setTimeout(r, ms))
}

function timeout(p, ms) {
  const orFail = sleep(ms).then(_ => { throw Error("timeout") })
  return Promise.race([ p, orFail ])
}

async function testTask(value) {
  await sleep(3000)
  return value
}

timeout(testTask("hello"), 5000)
  .then(console.log, console.error) // "hello"
  
timeout(testTask("world"), 1000)
  .then(console.log, console.error) // Error "timeout"
  

Another approach is to use a third-party library like bluebird that supports cancellation -

import { Promise } from "bluebird"

function makeCancellableRequest(url) {
    return new Promise(function(resolve, reject, onCancel) {
        var xhr = new XMLHttpRequest();
        xhr.on("load", resolve);
        xhr.on("error", reject);
        xhr.open("GET", url, true);
        xhr.send(null);
        // Note the onCancel argument only exists if cancellation has been enabled!
        onCancel(function() {
            xhr.abort();
        });
    });
}
Mulan
  • 129,518
  • 31
  • 228
  • 259