使用异步调用设计函数回调

时间:2019-05-24 16:10:25

标签: javascript

设计可与回调函数中的异步函数一起使用的代码时的最佳实践是什么,这是问题的简化视图。


有此更新函数可以进行一些异步函数调用,以将某些数据更新到某种存储中。

function update(){
  asyncfn(arg, () => {// Callback code});
}

然后有这两个按钮来调用更新功能

Updatebtn.onClick = update;

UpdateDisplaybtn.onClick = () => {
  update();
  displayUpdatedData();
}

第二个按钮将导致问题,因为将在update()真正完成之前调用displayUpdatedData(),因为它具有一个异步函数调用,该调用不会完成,而且我无法在update()中指定自己的回调因为它用作onClick事件的回调。

我对诺言并不了解,但是我知道我使用的异步功能不支持诺言。

我不是在寻找某种解决方法,而是在这种情况下寻找最佳实践。


更新

在了解最佳实践是使用承诺之后,我使用了The Coding Train的YouTube播放列表“ JavaScript Promises”来了解它们,这非常好,我想与任何想学习Promises的人分享

2 个答案:

答案 0 :(得分:1)

因此,如果您正在寻找最佳实践,我强烈建议您使自己熟悉诺言。 Javascript现在支持async / await语法,它允许您等待promise的响应,但是可以像普通函数一样或多或少地编写代码。我知道您是在说要使用的异步函数需要回调,并且不支持promise,但是您可以使用诸如bluebird之类的库将基于回调的函数转换为基于promise的函数(promisify),或者如果您位于节点中,它具有自己的本地承诺功能。

因此,您最终将得到如下结果:

import cbFn from 'cbFn'; //import or require your callback based function
import {promisify} from 'util';

const pFn = promisify(cbFn);

async function update() {
  await pFn()
}

...

UpdateDisplaybtn.onClick = async () => {
  await update();
  await displayUpdatedData() //await only needed if displayUpdatedData is also async / a promise
}

答案 1 :(得分:1)

如果您正在使用仅接受回调的函数,则可以将其包装在promise中,以便可以利用async / await。如果函数已经返回了一个Promise,则可以只使用async / await而不必将其包装。

通过这种方式,您仍然可以通过简单地将updatedisplayUpdatedData函数放入async函数和awaiting中来依次执行它们。 / p>

function callbackFunction (cb) {
  // ... stuff is happening
  cb('Data from the callback func');
}

async function update() {
  return new Promise( (resolve, reject) => {
    callbackFunction( (data) => {
      resolve(data); // or reject(); if failure
    });
    
  });
}

const doThings = async () => {
  const result = await update();
  console.log(result);
  // TODO: Display data from the result
};

doThings();