将拒绝从外部承诺传播到内部承诺

时间:2018-10-13 12:47:27

标签: javascript promise es6-promise

我创建了一个运行时间很长的Promise,并使用为创建手表Promise比赛而创建的这个简单函数进行了包装。

该功能如下:

export const promiseTimeout = (
  promise,
  timeoutMs = 10000, //10 secs
  message = 'Timeout reached, please try again',
) =>
  Promise.race([
    promise,
    new Promise((resolve, reject) =>
      setTimeout(() => {
        reject(message);
      }, timeoutMs),
    ),
  ]);

我打算使用它的方式是我将通过长期运行的Promise,这可能需要其他不可预测的资源,例如Internet,文件,系统设置等。

用法如下: const result = await promiseTimeout(longRunningFunction()) .catch(err => /* do something with the error , show toast or alert */);;

当前发生的情况是,每当达到超时时,它将调用catch,但 longRunningFunction 的操作仍将继续。

如果达到超时时间,如何停止对传递的Promise进行的操作?

1 个答案:

答案 0 :(得分:1)

  

如果达到超时,如何停止对参数传递的Promise的操作?

嘿,抱歉,我们don't have cancellation of async functions yet

但是请注意,承诺是一种价值,而不是一项行动,一旦有了承诺,我们就不会在JavaScript中取消可撤销的承诺,就无法取消该行动。

您唯一可以做的就是做类似the cancellation proposal的事情,并用令牌写上longRunningFunction

function longRunningFunction() {
   const signal = { requested: false };
   async function internal() {
     // your regular code here
     // whenever you can stop execution:
     if(signal.requested) {
       return; // and cancel internal operations
     }
   }
   let res = internal();
   res.signal = signal;
   return res;
}

然后将您的比赛写为:

export const promiseTimeout = (
  promise,
  timeoutMs = 10000, //10 secs
  message = 'Timeout reached, please try again',
) =>
  Promise.race([
    promise,
    new Promise((resolve, reject) =>
      setTimeout(() => {
        reject(message);
        if (promise.signal) promise.signal.requested = true;
      }, timeoutMs),
    ),
  ]);