2 回答

TA貢獻(xiàn)1826條經(jīng)驗(yàn) 獲得超6個(gè)贊
有不同的方法可以做到這一點(diǎn)。我不會(huì)涵蓋所有內(nèi)容。
選項(xiàng) 1:等待承諾
對(duì)于此示例,您將希望在函數(shù)內(nèi)運(yùn)行代碼async以利用關(guān)鍵字await。
更新您的 SMTP 和 PM2 函數(shù)以返回一個(gè) Promise。在 promise 內(nèi)部將處理邏輯并resolve("done")釋放 promise,以便代碼可以繼續(xù)。
module.exports = ({ host, port, username, key }) => {
return new Promise((resolve) => {
...
resolve("done");
});
}
現(xiàn)在您可以更新執(zhí)行代碼以利用承諾:
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();
選項(xiàng) 2:連鎖承諾
另一種方法是通過鏈接 Promise。我選擇不經(jīng)常這樣做,因?yàn)樗鼤?huì)變成一團(tuán)亂七八糟的嵌套邏輯。
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");
});
});
選項(xiàng) 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貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超4個(gè)贊
async
讓我們暫時(shí)忘掉函數(shù)。它們只是 Promises 之上的一點(diǎn)語法糖。如果您還沒有 Promise,那么它們對(duì)您沒有任何好處。
將 Promises 視為為您處理回調(diào)的包裝器對(duì)象。他們真的僅此而已。當(dāng)我們構(gòu)造一個(gè)新的 Promise時(shí),我們得到了特殊的resolve
和reject
函數(shù)。然后我們可以使用其中一個(gè)或兩個(gè)函數(shù)來代替?zhèn)鹘y(tǒng)的回調(diào)。因此,例如,如果我們想承諾setTimeout:
const timeoutAsPromised = (delay) => {
? return new Promise((resolve) => {
? ? setTimeout(resolve, delay);
? });
};
我們立即返回一個(gè) Promises。這很重要。我們的函數(shù)現(xiàn)在必須返回 Promise,以便可以立即使用它。但是代替回調(diào),我們使用resolvePromise 構(gòu)造函數(shù)給我們的函數(shù)。現(xiàn)在我們可以這樣稱呼它:
timeoutAsPromised(1000)
? .then(() => console.log('One second has passed!'));
對(duì)于您的用例,我們可以做很多相同的事情。只需獲取您的功能并將它們包裝在一個(gè) promisified 版本中:
const sftpAsPromised = (credentials) => {
? return new Promise((resolve) => {
? ? sftp(credentials, resolve);
? });
};
盡管取決于編寫者sftp和編寫方式,但從頭開始重寫它以返回 Promise 而不是進(jìn)行回調(diào)可能同樣容易:
module.exports = ({ host, port, username, key }) => {
? return new Promise((resolve) => {
? ? ...
? ? resolve('done')
? });
};
哎呀,如果你有很多這樣的異步函數(shù),并且它們都有相同的函數(shù)簽名(它們接受一個(gè)參數(shù),然后是一個(gè)回調(diào)),你甚至可以編寫一個(gè)小的 promisify 實(shí)用程序來處理它們:
const promisify = (fn) => (arg) => {
? return new Promise((resolve) => {
? ? fn(arg, resolve);
? });
};
const pm2AsPromised = promisify(pm2);
好的!現(xiàn)在讓我們簡單談?wù)刟sync / await。這些語法很可愛,但重要的是要始終記住它們只適用于 Promises。如果你有一些基于回調(diào)構(gòu)建的異步函數(shù),那么 async/await 對(duì)你來說毫無用處。
值得慶幸的是,我們剛剛完成了承諾回調(diào)函數(shù)的工作。所以讓我們創(chuàng)建一個(gè)包裝async函數(shù),然后await我們的 promisified 函數(shù)調(diào)用。您可以認(rèn)為await基本上只是替換.then方法。
const handlerServer = async () => {
? await sftpAsPromised(credentials);
? await pm2AsPromised(credentials);
};
handleServer();
希望這能解決問題!
添加回答
舉報(bào)