Обещания Javascript — обрабатывать возможное условие гонки

#javascript #es6-promise

#javascript #es6-обещание

Вопрос:

Недавно я столкнулся с этим вопросом в Интернете, и это решение. Тем не менее, я не до конца понимаю решение.

Вопрос:

 this.resources = {};

async function getResource (name) {

    if (this.resources[name]) {
        return this.resources[name]
    }

    const resource = new Resource(name)
    
    await resource.load()

    this.resources[name] = resource

    return resource
}
  

Здесь, в случае, если у нас есть вызов getResource с именем X и в течение времени load выполнения мы получаем другой вызов функции с тем же именем X, это может создать другой ресурс с именем X.

Решение этой проблемы:

 this.resources = {};

async function getResource (name) {

    if (this.resources[name]) {
        return this.resources[name]
    }

    const resource = new Resource(name)

    this.resources[name] = resource.load().then(()=>resource)

    return this.resource[name]
}
  

Теперь это решение означает, что сначала this.resources[name] будет содержаться объект Promise, а затем, как только обещание будет выполнено, он будет содержать загруженный ресурс.

Мой вопрос в том, что в случае, если мы ожидаем разрешения обещания, и поступит еще один вызов getResource с именем X, он передаст if оператор и еще раз вызовет new Resource(name) и дождется load завершения.

Но не приведет ли это к тому, что первый ресурс X this.resources[name] будет переопределен после завершения второго load ?

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

1. вы ошибаетесь, this.resources[name] ВСЕГДА будете содержать обещание, обещание, которое возвращается .then , то есть обещание, которое разрешает resource — кроме того, вам больше не нужно, чтобы эта функция была async

2. Но как это обещание обрабатывает потенциальное условие гонки?

3. Второй вызов будет ждать завершения первого. Две пользовательские функции javascript никогда не выполняются параллельно.

4. потенциального условия гонки не существует, поскольку this.resources[name] только когда-либо возвращается обещание resource.load().then и никогда не возвращается обещание resource.load()

Ответ №1:

поступает еще один вызов getResource с именем X, он передаст оператор if

Второй вызов будет ждать завершения первого. Две пользовательские функции javascript никогда не выполняются параллельно.

Вот почему первая версия не работает — выполнение функции заканчивается на await и, прежде чем оно продолжится, может произойти другой вызов.