Javascript 如何使代码异步?(谷歌浏览器扩展)
我正在开发一个GoogleChrome扩展,它从两台服务器收集数据并发送到另一个服务。我不明白如何使它异步。这些请求似乎很有效 我在谷歌上搜索了一些解释,但只找到了一些带超时的基本教程。另外,产品服务器接受Ajax请求,而交易服务器不接受(CORS错误)。所以我使用了XMLHttpRequestJavascript 如何使代码异步?(谷歌浏览器扩展),javascript,ajax,asynchronous,google-chrome-extension,promise,Javascript,Ajax,Asynchronous,Google Chrome Extension,Promise,我正在开发一个GoogleChrome扩展,它从两台服务器收集数据并发送到另一个服务。我不明白如何使它异步。这些请求似乎很有效 我在谷歌上搜索了一些解释,但只找到了一些带超时的基本教程。另外,产品服务器接受Ajax请求,而交易服务器不接受(CORS错误)。所以我使用了XMLHttpRequest document.addEventListener("DOMContentLoaded", function () { var createButton = document.getEleme
document.addEventListener("DOMContentLoaded", function () {
var createButton = document.getElementById("createButton");
createButton.addEventListener("click", function () {
getProducts();
getDeals();
}, false)
function getProducts() {
var list = [];
chrome.tabs.getSelected(null, function (tab) {
var Url = parseDealIdToUrl(tab.url)
$.get(Url, function (data, status) {
const jsonData = JSON.parse(JSON.stringify(data))
const productArray = jsonData.data
productArray.forEach(product => {
productList.push(new Product(product.id, product.deal_id, product.product_id, product.name, product.item_price, product.quantity, product.duration, product.discount_percentage, product.currency, product.sum, product.sum_formatted))
});
})
});
}
function getDeals(maxPages = 1, currentPage = 1, akquises = []) {
var akquiseList = akquises;
if (currentPage <= maxPages) {
var Url = dealUrl + currentPage
var xhr = new XMLHttpRequest();
xhr.open("GET", Url, true);
xhr.setRequestHeader("Authorization", "Token token=")
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
const akquiseArray = JSON.parse(xhr.responseText);
akquiseArray.forEach(akquise => {
akquiseList.push(new Akquise(akquise.name, akquise.id))
});
getDeals(handlePagination(xhr.getResponseHeader("Link")), currentPage + 1, akquiseList)
}
}
xhr.send();
}
}
}, false)
document.addEventListener(“DOMContentLoaded”,函数(){
var createButton=document.getElementById(“createButton”);
createButton.addEventListener(“单击”),函数(){
getProducts();
getDeals();
},错)
函数getProducts(){
var列表=[];
chrome.tabs.getSelected(空,函数(选项卡){
var Url=parseDealIdToUrl(tab.Url)
$.get(Url、函数(数据、状态){
const jsonData=JSON.parse(JSON.stringify(数据))
const productArray=jsonData.data
productArray.forEach(产品=>{
productList.push(新产品(Product.id、Product.deal\u id、Product.Product\u id、Product.name、Product.item\u价格、Product.quantity、Product.duration、Product.折扣\u百分比、Product.currency、Product.sum、Product.sum\u格式))
});
})
});
}
函数getDeals(maxPages=1,currentPage=1,akquises=[])){
var akquiseList=akquises;
如果(当前页){
akquiseList.push(新的Akquise(Akquise.name,Akquise.id))
});
getDeals(handlePagination(xhr.getResponseHeader(“链接”)),当前页面+1,akquiseList)
}
}
xhr.send();
}
}
},错)
我想调用这两个函数并等待两个列表都被填满,然后将数据发送到服务。任何想法都会帮助我 我不太清楚您所说的“异步化”是什么意思。正如wOxxOm所说,XMLHttpRequest是一种异步方法。你是说你不确定如何组合多个异步操作的结果?为了回答这个问题,我假设情况就是这样 基本异步性 为了分析异步函数的工作方式,让我们看一个简化的代码示例。下面我们有一个调用两个不同异步函数的主函数。运行此块时,控制台将记录一条
DONE
消息,1秒后记录Async 1 complete
,1秒后记录Async 2 complete
//版权所有2019谷歌有限责任公司。
//SPDX许可证标识符:Apache-2.0
(函数main(){
doAsync1();
doAsync2();
console.log('DONE');
})()
函数doAsync1(){
设置超时(()=>{
log('async1 complete');
}, 1000);
}
函数doAsync2(){
设置超时(()=>{
log('async2complete');
}, 2000)
}
之所以在其他语句之前记录DONE
,是因为doAsync1
和doAsync2
是异步的,它们需要几秒钟才能完成工作。在main
中调用doAsync1()
时,JS引擎将进入doAsync1
函数并开始执行行。第一行是setTimeout
调用。此函数接受其第一个参数,并计划在1000毫秒后执行
此时,JS引擎已经在doAsync1
中完成了它所能做的一切,因此它退出该函数并调用下一行doAsync2
。同样,doAsync2
为将来的执行和返回安排回调
接下来,引擎将执行console.log
行,使DONE
显示在控制台中
1000毫秒后,doAsync1计划的回调将运行execute并将Async 1 complete
记录到控制台。再过1000毫秒,doAsync2
计划的回调将记录async2完成
基本回调
现在让我们假设doAsync1
和doAsync2
生成一些数据,我们希望在main
中使用这些数据。在JS中,我们传统上使用回调在我们感兴趣的操作完成时获得通知
//版权所有2019谷歌有限责任公司。
//SPDX许可证标识符:Apache-2.0
函数doAsync1(回调){
设置超时(()=>{
log(“异步1已启动”);
const data=“异步1有效负载”;
回调(数据);
}, 1000);
}
函数doAsync2(回调){
设置超时(()=>{
log(“异步2已启动”);
const data=“异步2有效负载”;
回调(数据);
}, 2000);
}
(函数main(){
常量响应={};
doAsync1(handleAsync1);
doAsync2(handleAsync2);
功能手柄SYNC1(数据){
response.async1=数据;
handleComplete();
}
函数handleAsync2(数据){
response.async2=数据;
handleComplete();
}
函数handleComplete(){
if(response.hasOwnProperty('async1')和&response.hasOwnProperty('async2')){
console.log('DONE',response);
}
}
})();
承诺
虽然这样做的工作,它有点冗长。承诺是一次性回调的抽象,使得将工作块链接在一起变得更容易
//版权所有2019谷歌有限责任公司。
//SPDX许可证标识符:Apache-2.0
//setTimeout的预期版本
功能超时(持续时间){
返回新承诺(解决=>{
设置超时(解析、持续时间);
});
}
函数doAsync1(回调){
返回超时(1000)。然后(()=>{
log(“异步1已启动”);
const data=“异步1有效负载”;
返回数据;
});
}
函数doAsync2(回调){
返回超时(2000)。然后(()=>{
log(“异步2已启动”);
const data=“异步2有效负载”;
返回数据;
});
}
(函数main(){
//启动doAsync1和d