Как мне использовать await и async в этой функции? - PullRequest
0 голосов
/ 30 октября 2019

Я работаю над расширением Chrome, которое почти закончено. В настоящее время я получаю ответ от своей выборки, поскольку данные выбираются завершенными, а не в правильном порядке. Я думаю, мне придется использовать await и async, но я не знаю, как. Стоит отметить, что у меня есть «связь» между моим фоновым сценарием и сценарием содержимого, использующим sendMessage.

Я действительно пытался следовать этому руководству, и, вероятно, это очень легко выполнить, если вы уже делали это раньше, но я не сделалне понимаю, что делать с моей ценой => {} Учебник: https://dev.to/shoupn/javascript-fetch-api-and-using-asyncawait-47mp?fbclid=IwAR2Z5EPZ_rEJPTjB7fIVbO2b48rTqk1TOW13s12vzPewE4sn2T3ELzoGEF0

Content.js

function getPrices() {
    for (var i = 0; i < 35; i++) {
        chrome.runtime.sendMessage(
            {contentScriptQuery: "queryPrice", itemURL: skins[priceNumber]},
            price => {
                console.log(price);
            });

        priceNumber = priceNumber + 1;
    }
...
}

background.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
      if (request.contentScriptQuery == "queryPrice") {
        var url = "https://pixelboii.wtf/steamvalue.json";
        var skinFullName = request.itemURL;
        fetch(url)
            .then(res => res.json())
            .then(price => {
              sendResponse(price.items_list[skinFullName].price["7_days"].average);
            })
            .catch(err => { throw err });
        return true;  // Will respond asynchronously.
      }
    });

Все ответыприветствуются!

1 Ответ

0 голосов
/ 31 октября 2019

Fetch (и многие другие асинхронные методы) занимают неопределенное количество времени для запуска. Вот почему они асинхронные, они зависят от некоторого внешнего ресурса, который может занимать различное количество времени.

Вы не можете гарантировать, что порядок ответа совпадает с порядком вызовов. То, что вы можете сделать, это отправить request.itemURL в вызове sendResponse в качестве второго аргумента, а затем изменить ваш обратный вызов, чтобы использовать его, например,

Content.js

...
(price, url) => {
    console.log(`${url}: price: ${price}`);
});
...

Background.js

...
sendResponse(price.items_list[skinFullName].price["7_days"].average, request.itemURL);
...

Это позволит вам отслеживать, какие предметы имеют какую цену.

Если вам определенно нужно, чтобы они находились в определенном месте. Для заказа вам нужно будет подождать, пока все обратные вызовы не будут запущены. Это можно сделать, используя счетчик и увеличивая его перед вызовом sendMessage, затем уменьшая его в обратном вызове. Некоторый быстрый и грязный код для этого:

let counter = 0, results = {};
for(let i=0;i<35;i++){
    counter++;
    sendMessage(..., (price, url) => {
        counter--;
        results[url] = price;
        if(counter == 0){
            // finished all calls
            // print results
            console.log(results);
        }
    });
}

Чтобы напрямую ответить на вопрос: вам нужно создать оболочку для sendMessage, которая возвращает обещание, а затем использовать что-то вроде let results = await sendMessageWrapper(...). Использование await в цикле - это анти-паттерн, как объясняет это правило eslint .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...