【问题标题】:Promise lose custom function承诺失去自定义功能
【发布时间】:2021-09-20 04:38:58
【问题描述】:

这是一个代码示例:

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());

我在一个 promise 中添加了一个自定义函数。调用函数abort() 按预期工作。 在函数bar() 中,我使用then() 方法注销解析的值。 我知道bar() 的返回值是一个新的承诺。但它失去了自定义函数abort()

如何将自定义函数继承到新的 Promise 中?

【问题讨论】:

  • 一个promise不应该有一个方法来中止它。把它放在一个单独的地方,然后直接调用那个函数——不是在 promise 上,也绝对不是在后代 promise 上。你希望promise.then(_ => timeout(500)).abort() 做什么?

标签: javascript promise cancellation


【解决方案1】:

创建您自己的课程和subclass the native Promise。然后您可以保留自定义方法,因为.then() 将返回自定义类

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());

【讨论】:

【解决方案2】:

You cannot cancel/abort a Promise。一种方法是编写一个通用的 timeout 或类似的函数来处理长期承受的 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"
  

另一种方法是使用支持取消的第三方库,如 bluebird -

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();
        });
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2019-05-27
    • 2023-04-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    相关资源
    最近更新 更多