【问题标题】:Resolve promise return by Async function通过异步函数解决承诺返回
【发布时间】:2020-01-31 06:59:24
【问题描述】:

我读过 Async 函数隐式返回一个由返回解决的承诺。 有没有办法让 Async 函数返回该承诺,以便我们自己解决它?

我有一个用例,我调用一个 api,它接受一个将被异步调用的函数。

/**
 * 
 * @param {Array} keys - list of keys to get values
 */
let getStorageValues = async (keys) => {
    // chrome.storage.sync.get accepts second argument which is called asynchronously. 
    chrome.storage.sync.get(keys, (values) => {
        if (values) {
            return values;
        } else {
            return new Error('throw')
        }
    })

}

相反,我想要类似的东西

let getStorageValues = async (keys) => {
    let AsyncPromise = Async Function Promise.
    chrome.storage.sync.get(keys, (values) => {
        if (values) {
            AsyncPromise.resolve(values);
        } else {
            AsyncPromise.reject(new Error('throw'))
        }
    })

}

如果我可以访问 Async 函数返回的 Promise,我可以使用它来解析 chrome.storage.sync.get 中使用的 values 变量

【问题讨论】:

  • 您需要添加更多解释。 那个异步函数在哪里?你在哪里称呼它?可能你不需要看到承诺。如果你更清楚地说明你的目的,我可以说更多。
  • Is there a way to get that promise returned by Async function 通过调用该函数?
  • chrome.storage.sync.get 不返回承诺。你要么需要将它包装在一个 Promise 中并返回它,要么使用回调。只是把它放在一个异步函数中对你没有帮助。
  • 这能回答你的问题吗? How do I use Promise.all() with chrome.storage()?
  • 您没有在函数中的任何地方使用await。为什么要用async 标记它?

标签: javascript


【解决方案1】:

要获得与您想要的相似的东西(即导出解析和拒绝回调),您需要执行以下操作:

let getStorageValues = (keys) => { // Note: no async keyword because it is useless
    let resolve;
    let reject;

    let AsyncPromise = new Promise((a,b) => {
        resolve = a;
        reject = b;
    });

    chrome.storage.sync.get(keys, (values) => {
        if (values) {
            resolve(values);
        } else {
            reject(new Error('throw'))
        }
    })

    return AsyncPromise;
}

但这显然比平时要冗长得多:

let getStorageValues = (keys) => { // Note: no async keyword because it is useless
    return new Promise((resolve,reject) => {
        chrome.storage.sync.get(keys, (values) => {
            if (values) {
                resolve(values);
            } else {
                reject(new Error('throw'));
            }
        });
    }
}

在 node.js 上,您还可以修改您的代码以利用 util.promisify

const util = require('util');

let getStorageValues = util.promisify((keys,errorFirstCallback) => {
    chrome.storage.sync.get(keys, (values) => {
        if (values) {
            errorFirstCallback(null,values);
        } else {
            errorFirstCallback(new Error('throw'));
        }
    });
});

很遗憾,async 关键字无法按照您的意愿进行操作。

【讨论】:

  • 我认为util.promisify 只能承诺接受error first callback 的函数?
  • @AZ_ 是的,请参阅我的示例代码,了解如何将 OP 的代码转换为错误优先回调。它已经在我的答案中
  • @AZ_ 为清楚起见,我将更改 callback 参数的名称 - 我不会更改任何其他内容
  • 哦,我第一次没有看到包装回调,但现在更清楚为什么需要包装回调了。
猜你喜欢
  • 1970-01-01
  • 2019-03-19
  • 2022-01-26
  • 1970-01-01
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
相关资源
最近更新 更多