【问题标题】:Access promise instance that returns from async function访问从异步函数返回的 promise 实例
【发布时间】:2018-10-14 21:20:47
【问题描述】:

Async 函数自动返回 Promise - 我想知道是否有办法在函数内部获取这个 Promise 的这个实例 例如,如果我返回一个像这样的实际承诺:

const getSomePromise = () => {
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('success');
       }, 1000);
    })

    promise.someProp = 'myProp';
    return promise;
}

const promise = getSomePromise();
console.log(promise.someProp);

我想用纯异步函数实现同样的功能:

const sleep = ts => new Promise(resolve => setTimeout(resolve, ts));

const getSomePromise =  async () => {
     const p = await sleep(1000);
     // some how access the instance of the promise from within the async function 
     // for example this['someProp'] = 'myProp';
     // and return the all promise with this prop
     return 'sucess';
}
const promise = getSomePromise();
console.log(promise.someProp);

我可以这样做吗?

谢谢

【问题讨论】:

  • 不,这是不可能的。你想做什么,你想用.prop做什么?
  • 向我的 promise 对象添加一些标志 - 可以说可取消,如下所述:github.com/fangj/make-cancelable/blob/master/index.js - 我只想用纯异步函数做同样的事情 - 不使用 new Promise
  • 看看Fluture => github.com/fluture-js/Fluture。它可以包装承诺,并且已经提供取消。
  • @Adidi 取消信号应该是输入(函数的参数),而不是输出的一部分。

标签: javascript promise async-await


【解决方案1】:

向 Promise 添加属性几乎可以肯定是一个坏主意(稍后会在然而下详细介绍),但只是谈谈您将如何继续这样做:

我想知道是否有办法在函数中获取这个承诺的这个实例

不,没有。您可以在函数中创建一个 Promise 并返回它,但这不是函数返回的 Promise(它只会影响函数返回的 Promise 的解析方式)。

如果你想为返回的 Promise 添加一个属性,你必须使用非async 函数。你可以让函数的整个代码都不是async:

const sleep = ts => new Promise(resolve => setTimeout(resolve, ts));

const getSomePromise = () => {
    const p = sleep(1000).then(() => 'success');
    p.someProp = 'myProp';
    return p;
}
const promise = getSomePromise();
console.log(promise.someProp);

...或者您可以使用内部 async 函数,以便您可以使用 await 语义等:

const sleep = ts => new Promise(resolve => setTimeout(resolve, ts));

const getSomePromise = () => {
    const p = (async () => {
        await sleep(1000);
        return 'success';
    })();
    p.someProp = 'myProp';
    return p;
}
const promise = getSomePromise();
console.log(promise.someProp);

然而:向 Promise 添加属性几乎肯定是个坏主意。相反,让 promise 解析为具有分辨率和额外 someProp 属性的对象:

const sleep = ts => new Promise(resolve => setTimeout(resolve, ts));

const getSomePromise = async () => {
    const p = await sleep(1000);
    // some how access the instance of the promise from within the async function 
    // for example this['someProp'] = 'myProp';
    // and return the all promise with this prop
    return {
        result: 'success',
        someProp: 'myProp'
    };
}
getSomePromise()
    .then(resolution => {
        console.log(resolution.someProp);
    });

【讨论】:

  • 你能解释一下为什么是almost certainly a bad idea 吗?如果我想为 promise 的实例添加功能,例如取消:github.com/fangj/make-cancelable/blob/master/index.js - 为什么这是个坏主意?它对我来说似乎很优雅,然后现在返回一个带有我需要记住的键的复杂对象
  • @Adidi - 因为它无法在标准的 Promise 操作中存活(例如 then)。如果您真的想携带有关 Promise 本身而不是其分辨率值的信息,最好的选择是 Promise 子类(这意味着您不能使用 async 函数)。
  • 可能会传递一个令牌以进行取消。
  • @BenjaminGruenbaum - 是的 - 这是 axios 所做的,也是我尝试做的 - 包装了他们的解决方案,所以我总是得到取消功能,因为我认为他们的 api 取消非常冗长和笨拙跨度>
猜你喜欢
  • 1970-01-01
  • 2020-07-09
  • 2023-03-08
  • 2020-07-09
  • 2017-10-16
  • 1970-01-01
  • 2018-04-13
  • 2019-10-23
  • 1970-01-01
相关资源
最近更新 更多