Asyn c функции и параллелизм параметров объекта - PullRequest
0 голосов
/ 29 февраля 2020

Итак, сегодня я столкнулся с этой ошибкой, которая потребовала у меня целую вечность, чтобы выяснить:

async function embed (url, embedOptions={}) => {
    embedOptions.url = url;
    console.log("Before:");
    console.log(url)
    console.log(embedOptions.url)
    const accessToken = await getAccessToken()
    const requestOptions = {
        hostname: 'api.twitter.com',
        port: 443,
        method: 'GET',
        path: '/1.1/statuses/oembed.json?' + qs.stringify(embedOptions),
        headers: {
            'Authorization': 'Bearer ' + accessToken,
        },
    }

    console.log("After")
    console.log(url)
    console.log(embedOptions.url)

    return new Promise((resolve, reject) =>
        https.request(requestOptions, res => {
            let data = ''
            res.on('data', chunk => data += chunk)
            res.on('end', () => resolve(JSON.parse(data)))
        }).end()
    )
}

эта функция вызывается по трем различным URL-адресам, которые генерируют вывод:

Before:
https://twitter.com/326665662/statuses/1233300061154664453
https://twitter.com/326665662/statuses/1233300061154664453
Before:
https://twitter.com/36262503/statuses/1233462038854283264
https://twitter.com/36262503/statuses/1233462038854283264
Before:
https://twitter.com/929823128259387392/statuses/1233431896081629184
https://twitter.com/929823128259387392/statuses/1233431896081629184
After
https://twitter.com/326665662/statuses/1233300061154664453
https://twitter.com/929823128259387392/statuses/1233431896081629184
After
https://twitter.com/36262503/statuses/1233462038854283264
https://twitter.com/929823128259387392/statuses/1233431896081629184
After
https://twitter.com/929823128259387392/statuses/1233431896081629184
https://twitter.com/929823128259387392/statuses/1233431896081629184

I ' Я вполне уверен, что я выяснил, почему это происходит в основном, когда const accessToken = await getAccessToken() вызывается, функция приостанавливается, но следующий вызов функции embed происходит и перезаписывает embedOptions.url в ссылке на объект embedOptions, потому что все вызовы где сделанный со ссылкой на тот же объект, объект изменяется для всех вызовов функций. Это верно? И если это лучший способ защитить себя от повторения той же ошибки в будущем?

1 Ответ

0 голосов
/ 29 февраля 2020

Вы правы. Любой объект, переданный вашей функции, будет передан по ссылке и изменен, когда вы установите пропеллер URL.

Самый простой способ защититься от этих ошибок - быть осторожным, чтобы не изменять объекты. Альтернативой является создание новых объектов, используя значения из вашего embedOptions:

const embedCopy = Object.assign({}, embedOptions);
embedCopy.url = url;

. Это будет работать, если ваш объект не содержит объекты в качестве значений, и в этом случае вам нужно будет сделать глубокую копию ваш объект.

Существует множество библиотек, которые могут с этим справиться, например lodash или ramda.

...