当前位置: 首页 > 知识库问答 >
问题:

如何“等待”回调返回?

燕鸿波
2023-03-14

使用以下示例中的简单回调时:

test() {
  api.on( 'someEvent', function( response ) {
    return response;
  });
}

如何将函数更改为使用异步/等待?具体地说,假设某个事件保证被调用一次并且只有一次,我希望函数测试是一个异步函数,直到执行回调才返回,例如:

async test() {
  return await api.on( 'someEvent' );
}

共有3个答案

韩夕
2023-03-14

异步/等待是神奇的。您可以创建一个函数asPromise,以处理此类情况:

function asPromise(context, callbackFunction, ...args) {
    return new Promise((resolve, reject) => {
        args.push((err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
        if (context) {
            callbackFunction.call(context, ...args);
        } else {
            callbackFunction(...args);
        }
    });
}

然后在你想要的时候使用它:

async test() {
    return await this.asPromise(this, api.on, 'someEvent');
}

arg的数量是可变的。

欧阳杰
2023-03-14

很烦人的是,没有一个简单的解决方案,包装返回新的Promise(...)是模糊的,但是我已经找到了一个可以使用util.promisify解决方案(实际上它也做了相同的包装,只是看起来更好)。

function voidFunction(someArgs, callback) {
  api.onActionwhichTakesTime(someMoreArgs, (response_we_need) => {
    callback(null, response_we_need);
  });
}

上述函数尚未返回任何内容。我们可以通过执行以下操作使其返回传入回调的响应的promise

const util = require('util');

const asyncFunction = util.promisify(voidFunction);

现在我们可以真正地等待回调

async function test() {
  return await asyncFunction(args);
}

使用util.promisify时的一些规则

  • 回调必须是将被promisify
  • 的函数的最后一个参数
  • 假定的回调必须以(err, res)=

有趣的是,我们不需要专门编写回调实际上是什么。

钱毅
2023-03-14

async/wait不是魔术。异步函数是一个可以为您打开Promises的函数,因此您需要api.on()返回Promise才能正常工作。像这样的东西:

function apiOn(event) {
  return new Promise(resolve => {
    api.on(event, response => resolve(response));
  });
}

然后

async function test() {
  return await apiOn( 'someEvent' ); // await is actually optional here
                                      // you'd return a Promise either way.
}

但这也是一个谎言,因为异步函数本身也会返回promise,因此您实际上不会从test()中获取值,而是获取一个值的promise,您可以这样使用:

async function whatever() {
  // snip
  const response = await test();
  // use response here
  // snip
}
 类似资料:
  • 使用以下示例中的简单回调时: 如何将函数更改为使用异步/等待?具体地说,假设某个事件保证被调用一次并且只有一次,我希望函数测试是一个异步函数,直到执行回调才返回,例如:

  • 问题内容: 我有一个需要登录的服务器端功能。如果用户已登录,则函数将在成功返回1。如果没有,该函数将返回登录页面。 我想使用Ajax和jQuery调用该函数。我要做的是使用普通链接提交请求,并应用点击功能。如果用户未登录或功能失败,我希望Ajax调用返回true,以便href触发。 但是,当我使用以下代码时,该函数在Ajax调用完成之前退出。 如何将用户正常重定向到登录页面? 问题答案: 如果您不

  • 我有一个windows服务,我从另一个开发人员继承,它运行非常慢,并有许多对eBay API的缓慢调用。我希望在没有太多重构的情况下加快它。 我刚刚开始研究使用C#Async/Await来尝试让这些缓慢的调用运行异步。以下是我试图实现的目标: 如何获取返回的类型以便使用它们?我尝试使用,但它只有属性可用。

  • 问题内容: 我的代码在javascript中看起来像这样: 在完成所有这些异步调用之后,我想计算所有数组的最小值。 我要如何等待所有人? 我现在唯一的想法是拥有一个名为done的布尔数组,并在第i个回调函数中将done [i]设置为true,然后说while(不是全部都完成了){} 编辑:我想一个可能但很丑陋的解决方案是在每个回调中编辑完了的数组,然后如果每个回调中都设置了所有其他完成,则调用一个

  • 我用webpack建立了一个浏览器umd库。 我正在侦听输入文件的onchange事件。当有人提交图像/文件时,它会将其转换为base64。我试图让它尽可能看起来不那么明显,所以我使用了promises和wait/asynchttps://blog.shovonhasan.com/using-promises-with-filereader/. 但是,有一个问题-当我调用convertToBase