2 回答
TA贡献1826条经验 获得超6个赞
有不同的方法可以做到这一点。我不会涵盖所有内容。
选项 1:等待承诺
对于此示例,您将希望在函数内运行代码async以利用关键字await。
更新您的 SMTP 和 PM2 函数以返回一个 Promise。在 promise 内部将处理逻辑并resolve("done")释放 promise,以便代码可以继续。
module.exports = ({ host, port, username, key }) => {
return new Promise((resolve) => {
...
resolve("done");
});
}
现在您可以更新执行代码以利用承诺:
const fs = require("fs");
const sftp = require("./_uploader/sftp");
const pm2 = require("./_uploader/pm2");
const credentials = {
host: "",
port: 123,
username: "",
key: "key",
};
const runApp = async () => {
await sftp(credentials);
await pm2(credentials);
console.log("done");
}
runApp();
选项 2:连锁承诺
另一种方法是通过链接 Promise。我选择不经常这样做,因为它会变成一团乱七八糟的嵌套逻辑。
const fs = require("fs");
const sftp = require("./_uploader/sftp");
const pm2 = require("./_uploader/pm2");
const credentials = {
host: "",
port: 123,
username: "",
key: "key",
};
sftp(credentials).then(result1 => {
pm2(credentials).then(result2 => {
console.log("done");
});
});
选项 3:承诺所有
另一种选择是使用Promise.all
const fs = require("fs");
const sftp = require("./_uploader/sftp");
const pm2 = require("./_uploader/pm2");
const credentials = {
host: "",
port: 123,
username: "",
key: "key",
};
Promise.all([
sftp(credentials),
pm2(credentials)
]).then(result => {
console.log("done");
});
TA贡献1796条经验 获得超4个赞
async
让我们暂时忘掉函数。它们只是 Promises 之上的一点语法糖。如果您还没有 Promise,那么它们对您没有任何好处。
将 Promises 视为为您处理回调的包装器对象。他们真的仅此而已。当我们构造一个新的 Promise时,我们得到了特殊的resolve
和reject
函数。然后我们可以使用其中一个或两个函数来代替传统的回调。因此,例如,如果我们想承诺setTimeout:
const timeoutAsPromised = (delay) => {
return new Promise((resolve) => {
setTimeout(resolve, delay);
});
};
我们立即返回一个 Promises。这很重要。我们的函数现在必须返回 Promise,以便可以立即使用它。但是代替回调,我们使用resolvePromise 构造函数给我们的函数。现在我们可以这样称呼它:
timeoutAsPromised(1000)
.then(() => console.log('One second has passed!'));
对于您的用例,我们可以做很多相同的事情。只需获取您的功能并将它们包装在一个 promisified 版本中:
const sftpAsPromised = (credentials) => {
return new Promise((resolve) => {
sftp(credentials, resolve);
});
};
尽管取决于编写者sftp和编写方式,但从头开始重写它以返回 Promise 而不是进行回调可能同样容易:
module.exports = ({ host, port, username, key }) => {
return new Promise((resolve) => {
...
resolve('done')
});
};
哎呀,如果你有很多这样的异步函数,并且它们都有相同的函数签名(它们接受一个参数,然后是一个回调),你甚至可以编写一个小的 promisify 实用程序来处理它们:
const promisify = (fn) => (arg) => {
return new Promise((resolve) => {
fn(arg, resolve);
});
};
const pm2AsPromised = promisify(pm2);
好的!现在让我们简单谈谈async / await。这些语法很可爱,但重要的是要始终记住它们只适用于 Promises。如果你有一些基于回调构建的异步函数,那么 async/await 对你来说毫无用处。
值得庆幸的是,我们刚刚完成了承诺回调函数的工作。所以让我们创建一个包装async函数,然后await我们的 promisified 函数调用。您可以认为await基本上只是替换.then方法。
const handlerServer = async () => {
await sftpAsPromised(credentials);
await pm2AsPromised(credentials);
};
handleServer();
希望这能解决问题!
添加回答
举报