程式語言 - Node.js - 如何透過Promise等待事件完成



參考資訊:
https://stackoverflow.com/questions/5010288/how-to-make-a-function-wait-until-a-callback-has-been-called-using-node-js

main.js

var r = ''; 
var vbox = require('virtualbox');

vbox.list(function(vms, error) {
    r = vms;
});

console.log('vm: %s', r);

執行

$ node main.js
    [2023-08-15 01:14:04.539] [INFO] VirtualBox - linux
    [2023-08-15 01:14:04.546] [INFO] VirtualBox - Listing VMs
    vm: 

由於Node.js都是透過Callback處理方式(Asynchronous),因此,如上面例子,當呼叫vbox.list()時,vbox.list()的動作已經完成,因此,會直接往下走,但是最終結果卻是要在Callback才會知道,遇到這種情況,一般會透過Event做等待,直到Callback處理完成後才把結果列印出來,不過,在Node.js的應用上,一般是使用Promise()做等待的動作,如下修改範例:

var vbox = require('virtualbox');

async function start() {
    var r = '';

    await new Promise((resolve, reject) => {
        vbox.list(function(vms, error) {
            r = vms;
            resolve('ok');
        });
    });

    console.log('vm: %s', r);
}

start();

呼叫resolve()並且傳入隨意字串,代表允許Promise回傳成功的結果(代表Event已經完成),反之,如果呼叫reject()並且傳入隨意字串,代表發生錯誤,Promise將會throw error,而error字串內容則是設定給reject()的字串

$ node main.js
    [2023-08-15 01:32:12.109] [INFO] VirtualBox - linux
    [2023-08-15 01:32:12.115] [INFO] VirtualBox - Listing VMs
    [2023-08-15 01:32:12.130] [INFO] VirtualBox - Virtualbox version detected as 6
    vm: { '8591d090-e95a-423a-b99d-cf558bd0d245': [Object] }