Как сделать асинхронные JavaScript-установщики? - PullRequest
2 голосов
/ 29 апреля 2019

Я пытаюсь создавать асинхронные сеттеры, используя ключевые слова async / await.

Вот некоторые фальшивые функции базы данных, которые занимают время

function getProjectFromDatabase() {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve('My cool project!'), 500) // 500ms latency
    });
}

function setProjectToDatabase(projectName) {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve('set!'), 500) // 500ms latency
    });
}


Вот пример реализации для пользователя

let user = {

    // Getter
    get project() {
        return (async () => {
            return await getProjectFromDatabase();
        })();
    },

    // Setter
    set project(projectName) {
        return (async () => {
            return await setProjectToDatabase(projectName);
        })();
    },

    // Method 
    setProject(projectName) {
        return (async () => {
            return await setProjectToDatabase(projectName);
        })();
    }
};


А вот пример использования

(async function() {
    console.log(await user.project); // Getter works!
    await user.setProject('My new cool project!'); // Method works!
    await (user.project = 'Another project'); // Setter doesn't work...
})();


Но возвращаемое значение из функции setter игнорируется.

Как я мог это сделать?

Ответы [ 2 ]

2 голосов
/ 29 апреля 2019

Выражение присваивания всегда вычисляется с правой стороны.

  a.b.c = "This is what it gets evaluated to"

изменить это невозможно.

0 голосов
/ 29 апреля 2019

Обычно сеттер устанавливает некоторое значение, и вам не нужно возвращаемое значение.В традиционном объекте это может быть другое свойство (вероятно, не предназначенное для непосредственного использования).В переводе на что-то похожее на DB, установщик отправит INSERT или UPDATE, и будет установлено новое значение.

Ваш код в установщике на самом деле не , настройка ничего.Если бы это был фактический вызов БД, вы бы сохранили какое-то значение в базе данных, а затем при следующем вызове получателя получило бы новое значение.Если вы добавите что-то подобное в вызов DB вентилятора, вы получите нечто более похожее на традиционную логику получения / установки:

const a_user = {project: 'My cool project!'} // some fake db object

function getProjectFromDatabase() {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve(a_user.project), 500) // 500ms latency
    });
}

function setProjectToDatabase(projectName) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            a_user.project = projectName // actually set something
            resolve(a_user.project)      // caller of setter doesn't care about return value, but we still need to resolve so async works.
        }, 500) // 500ms latency
    });
}
let user = {

    // Getter
    get project() {
        return (async () => {
            return await getProjectFromDatabase();
        })();
    },
    // Setter
    set project(projectName) {
        return (async () => {
            return await setProjectToDatabase(projectName);
        })();
    },

};

(async function() {
    console.log(await user.project); // Getter works!
    await (user.project = 'Another project'); // 
    console.log(await user.project); // new value has been set
})();
...