等待由同步函数包裹的嵌套函数 Javascript

Await a nested function wrapped by a sync func Javascript

提示很简单,但不幸的是我找不到解决方案。

我必须提交创建 API 然后更新 API。通常,我可以承诺,async/await,甚至回调。但是,createAPI 由 formData 函数 (getLength) 包装,因为它需要附加一个文件。因此,我无法在触发更新之前等待内部 API。

由于 getLength 没有 return 任何东西并且它不是一个承诺,我不确定我可以如何解决这个问题?谢谢!

const createFunc = async () => {
    formData.getLength(async (err, length) => {
        await platformAPI
            .createAPI(formData, length)
            .then((res) => {
                if (res !== 201) {
                    console.log("something went wrong")
                }
                console.log("it works") 
            });
    });
}


const apiFunc = () => {
    createFunc().then(() => updateApi())
}

您可以承诺 formData.getLength。要么使用 Node 的 util.promisify 来获取 getLength 的 promified 版本,要么自己进行 promisify,如下所示:

// Promisify getLength:
const promiseLength = formData =>
    new Promise((resolve, reject) =>
        formData.getLength((err, length) => err ? reject(err) : resolve(length))
    );

const createFunc = () =>
    promiseLength(formData).then(length =>
        platformAPI
        .createAPI(formData, length)
        .then(res => {
            if (res !== 201) console.log("something went wrong")
            else console.log("it works"); // Only print this in the else-case
            return res; // Better return the value
        });
    );

请注意,当该函数中的唯一语句是 await 时,async 没有多大用处。在那种情况下,只需 return 等待的表达式并删除 async 关键字。而你第二次使用 async 甚至没有 await... 所以那是没用的。

您可以使用 Promise 构造函数将 .getLength 转换为基于 Promise 的 API,然后您可以 await:

const createFunc = async () => {
    const length = await new Promise ((rs, rj) => {
      formData.getLength((err, length) => {
        if(err)
          rj(err);
        else
          rs(length);
      });
    })
    //This part with the `then` was OK, but since you're already using `async/await`, there's no reason why you shouldn't use it here too
    const res = await platformAPI.createAPI(formData, length)
    if (res !== 201) {
      console.log("something went wrong")
    }
    console.log("it works")
}


const apiFunc = () => {
    createFunc().then(() => updateApi())
}

我认为您将实现分开,因为 formData.getLength 函数不是 promise 函数。你不应该一起使用回调和等待。我认为这不是一个好习惯。如果我们可以使用 await 始终使用该格式,它会更干净。

const getLengthFunc = new Promise(function(resolve, reject) {
  formData.getLength((err, length) => {
    if(err)
      reject('error');
    
    resolve(length)
  }
});

const createFunc = async () => {
  try{
    const length = await getLengthFunc();
    const res = await platformAPI.createAPI(formData, length);

    if (res !== 201)
       console.log("something went wrong")
            
    console.log("it works")
  }catch(e){
    console.log(e)
  }
}


const apiFunc = () => {
    createFunc().then(() => updateApi())
}