如何在此函数中使用等待和异步?

时间:2019-10-30 20:15:20

标签: javascript function google-chrome-extension fetch

我正在开发一个即将完成的Chrome扩展程序。当前,由于数据获取已完成,而不是正确的顺序,因此我从获取中获得了响应。我猜我将不得不使用await和async,但是我不确定如何使用。值得注意的是,我使用sendMessage在后台脚本和内容脚本之间建立了“联系”。

我确实尝试按照本教程进行操作,如果您之前曾经阅读过本教程,则可能非常容易,但是我不知道如何处理我的价格=> {} 教程:JsonPointer

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 :(得分:0)

提取(和许多其他异步方法)花费的时间不确定。这就是为什么它们异步的原因,它们依赖于一些外部资源,这些资源可能会花费可变的时间。

您不能确保响应顺序与呼叫顺序相同。您可以 做的是将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(...)的包装。如this eslint rule所述,在循环中使用await是一种反模式。