Как я могу получить значение асинхронного и передать функции?

#javascript #fs

#javascript #fs

Вопрос:

Мне нужно получить значение mtime и вернуть как результат функции lastSave, но я получаю undefined . Я знаю, что могу использовать fs.statSync(«. /Data.xlsx «), чтобы получить это значение. Я использую fs.stat() в качестве примера для асинхронности внутри функции.

 const lastSave = async (file) => {
    const momento = await fs.stat(file, function (err, stats) {
        var mtime = stats.mtime;
        console.log("interno", mtime);    // this works
        return mtime
    });
    return momento
}

console.log(lastSave('./Data.xlsx'))  // this writes "undefined"
 

Комментарии:

1. lastSave это асинхронная функция, которая означает, что она возвращает обещание. Чтобы получить его возвращаемое значение, либо создайте цепочку then() методов: lastSave('./Data.xlsx').then(data => console.log(data)).catch(e => console.log(e)); или вызовите эту функцию в другой асинхронной функции и await она.

2. Также рассмотрите возможность использования API fs модуля на основе обещаний. В настоящее время вы используете API обратного вызова, который не возвращает обещание, поэтому ожидание fs.stat не будет работать. Вы могли бы создать новое обещание с помощью конструктора обещаний, но лучше всего использовать API fs модуля на основе обещаний.

3. Для использования вам нужна версия promise fs.stat() await . nodejs.org/api/fs.html#fs_promise_example

4. @Yousaf не будет работать, поскольку OP использует обратный вызов в fs.stat()

5. @charlietfl да, я упоминал, что в моем втором комментарии OP необходимо использовать API fs модуля на основе обещаний.

Ответ №1:

Используйте вариант синхронизации функции.

 const fs = require('fs');

const lastSave = file => {
    return fs.statSync(file).mtime;
}

console.log(lastSave('./Data.xlsx'));
 

Если нет версии синхронизации, оберните вызов в асинхронную функцию и вызовите ее:

 const fs = require('fs');

const lastSave = file => {
    return new Promise(done => fs.stat(file, function (err, stats) {
        var mtime = stats.mtime;
        console.log("interno", mtime);    // this works
        done(mtime);
    }));
}

(async () => {
    console.log(await lastSave('./Data.xlsx'));
})();
 

Вы можете использовать вариант на основе обещаний:

 const fs = require('fs/promises');

const lastSave = async file => {
    return (await fs.stat(file)).mtime;
}

(async () => {
    console.log(await lastSave('./Data.xlsx'));
})();

 

В качестве альтернативы вы можете пообещать свою асинхронную функцию:

 const fs = require('fs');
const util = require('util');

const lastSave = async file => {
    return (await util.promisify(fs.stat)(file)).mtime;
}

(async () => {
    console.log(await lastSave('./Data.xlsx'));
})();
 

Альтернативы для

 (async () => {
    console.log(await lastSave('./Data.xlsx'));
})();
 

являются ли

 lastSave('./Data.xlsx').then(console.log);
 

и

 lastSave('./Data.xlsx').then(result => { console.log(result); });
 

Комментарии:

1. Я полагаю, вы имеете в виду «использовать асинхронную версию»

2. @charlietfl Нет, я имею в виду «Использовать вариант синхронизации» , как в fs.statSync .

3. Мой плохой… Я пропустил эту часть примера