为什么我把 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();
});
}
renameSync
是 rename
的同步版本。它不接受回调作为参数;它只接受 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);
});
}
(提示:我使用的是基于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();
});
}
renameSync
是 rename
的同步版本。它不接受回调作为参数;它只接受 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);
});
}