为什么我把 resolve() 放到 fs 的回调函数里,promise 没有 return

Why if I put resolve() into the callback function of fs, the promise doesn't return

(提示:我使用的是基于koa的nodejs框架eggjs

下面的代码可以 运行 successfully.But 如果我将 resolve() 放入 fs.renameSync() 的回调函数中,承诺不会 return 任何东西,并且请求保持 pending 状态。

这是什么原因造成的?这跟执行顺序有关系吗?


 async uploadAsset(assetName, file) {
    const { app } = this;
    const logger = this.logger;
    return new Promise(function(resolve, reject) {
      fs.renameSync(file.filepath, `${app.config.multipart.projectAssetLocalPath}${assetName}`, err => {
        if (err) {
          logger.warn(err);
          reject();
        }
      });
      resolve();
    });
  }

renameSyncrename 的同步版本。它不接受回调作为参数;它只接受 oldpath and a newpath。如果传递第三个参数,它将被忽略;您传递的回调函数永远不会被调用。

如果您希望它基于回调,请改用 fs.rename确实 接受回调。

你的resolve此刻也在回调外面,应该在里面的时候:

async uploadAsset(assetName, file) {
  const { app } = this;
  const logger = this.logger;
  return new Promise(function(resolve, reject) {
    fs.rename(file.filepath, `${app.config.multipart.projectAssetLocalPath}${assetName}`, err => {
      if (err) {
        logger.warn(err);
        reject();
      }
      resolve();
    });
  });
}

或者使用 fs.promises 代替,无需自己构建 Promise 即可完成此操作。

async uploadAsset(assetName, file) {
  const { app } = this;
  const logger = this.logger;
  return fs.promises.rename(file.filepath, `${app.config.multipart.projectAssetLocalPath}${assetName}`)
    .catch((err) => {
      logger.warn(err);
      throw new Error(err);
    });
}