首页 \ 问答 \ 取消隐藏和加载webview的顺序是否会影响性能?(Does the order of unhiding and loading a webview affect performance?)

取消隐藏和加载webview的顺序是否会影响性能?(Does the order of unhiding and loading a webview affect performance?)

在我的应用程序中,我有一个带有进度条的加载视图,因此用户可以观看PDF的下载进度。 下载完成后,我取消隐藏webview,然后调用loadRequest。 我只是想知道是否有任何区别:

[self.webView setHidden:NO];

[self.webView loadRequest:[NSURLRequest requestWithURL:localURL]];

[self.webView loadRequest:[NSURLRequest requestWithURL:localURL]];

[self.webView setHidden:NO];

我问,因为我假设loadRequest发生在自己的队列中,所以我认为没有任何明显的差异。


In my app I have a loading view with a progress bar so the user can watch a PDF's download progress. When the download completes I unhide the webview and then call loadRequest. I was just wondering if there is any difference between:

[self.webView setHidden:NO];

[self.webView loadRequest:[NSURLRequest requestWithURL:localURL]];

Versus

[self.webView loadRequest:[NSURLRequest requestWithURL:localURL]];

[self.webView setHidden:NO];

I ask because I assumed loadRequest happens in its own queue, so I thought there couldn't be any visible differences.


原文:https://stackoverflow.com/questions/17335166
更新时间:2023-03-11 10:03

最满意答案

当我将其注销时,为什么我的问题变量为空? 有明显的结果与它相结合。

这里的一个主要问题是.concat()返回一个新数组。 它不会将项添加到现有阵列上。

你可以改变这个:

issues.concat(JSON.parse(body).issues);

对此:

issues = issues.concat(JSON.parse(body).issues);

确保保留新的连锁数组。 这是一个非常常见的错误。


您也可能在数组中遇到排序问题,因为您正在运行for循环,它会同时启动一大堆请求,结果可能会或可能不会以正确的顺序返回。 您仍将获得正确的问题总数,但它们可能不符合要求的顺序。 我不知道你是否有问题。 如果这是一个问题,我们也可以建议修复。

一个更普遍的问题:这种方法是解决我想要实现的目标的最佳方式吗? 我认为即使我的代码确实有效,异步性的本质意味着结果可能以错误的顺序连接起来。

除了也可以修复的订购问题,这是一种合理的做事方式。 我们需要了解有关您的API的更多信息,以了解这是否是使用API​​获取结果的最有效方式。 通常,您希望避免对同一服务器进行N次重复API调用,而是进行一次API调用以获取所有结果。

我应该只使用同步请求库吗?

绝对不。 node.js需要学习如何进行异步编程。 对于大多数人来说,这是一个学习步骤,但是你是如何从node.js获得最佳性能的,应该学习和使用它。


这是一种使用promises进行同步和错误传播的可靠顺序收集所有结果的方法(这对于node.js中的异步处理非常有用):

// promisify the request() function so it returns a promise
// whose fulfilled value is the request result
function requestP(url) {
    return new Promise(function(resolve, reject) {
        request(url, function(err, response, body) {
            if (err || response.statusCode !== 200) {
                reject({err: err, response: response});
            } else {
                resolve({response: response, body: body});
            }
        });
    });
}

Donedone.prototype.getAllActiveIssues = function() {
    var url = this.url;
    return requestP(url + `/issues/all_active.json?take=500`).then(function(results) {
        var data = JSON.parse(results.body);
        var totalIssues = data.total_issues;
        var promises = [];
        for (let i = 0; i < totalIssues; i+= 500) {
            promises.push(requestP(url + `/issues/all_active.json?skip=${i}&take=500`).then(function(results) {
                return JSON.parse(results.body).issues;                
            }));
        }
        return Promise.all(promises).then(function(results) {
            // results is an array of each chunk (which is itself an array) so we have an array of arrays
            // now concat all results in order
            return Array.prototype.concat.apply([], results);
        })
    });
}

xxx.getAllActiveIssues().then(function(issues) {
    // process issues here
}, function(err) {
    // process error here
})

Why is my issues variable empty when I log it out? There are clearly results to concatenate with it.

A main problem here is that .concat() returns a new array. It doesn't add items onto the existing array.

You can change this:

issues.concat(JSON.parse(body).issues);

to this:

issues = issues.concat(JSON.parse(body).issues);

to make sure you are retaining the new concatenated array. This is a very common mistake.


You also potentially have sequencing issues in your array because you are running a for loop which is starting a whole bunch of requests at the same time and results may or may not arrive back in the proper order. You will still get the proper total number of issues, but they may not be in the order requested. I don't know if that is a problem for you or not. If that is a problem, we can also suggest a fix for that.

A more general question: is this approach the best way to go about what I'm trying to achieve? I figured that even if my code did work, the nature of asynchronicity means it's entirely possible for the results to be concatenated in the wrong order.

Except for the ordering issue which can also be fixed, this is a reasonable way to do things. We would have to know more about your API to know if this is the most efficient way to use the API to get your results. Usually, you want to avoid making N repeated API calls to the same server and you'd rather make one API call to get all the results.

Should I just use a synchronous request library?

Absolutely not. node.js requires learning how to do asynchronous programming. It is a learning step for most people, but is how you get the best performance from node.js and should be learned and used.


Here's a way to collect all the results in reliable order using promises for synchronization and error propagation (which is hugely useful for async processing in node.js):

// promisify the request() function so it returns a promise
// whose fulfilled value is the request result
function requestP(url) {
    return new Promise(function(resolve, reject) {
        request(url, function(err, response, body) {
            if (err || response.statusCode !== 200) {
                reject({err: err, response: response});
            } else {
                resolve({response: response, body: body});
            }
        });
    });
}

Donedone.prototype.getAllActiveIssues = function() {
    var url = this.url;
    return requestP(url + `/issues/all_active.json?take=500`).then(function(results) {
        var data = JSON.parse(results.body);
        var totalIssues = data.total_issues;
        var promises = [];
        for (let i = 0; i < totalIssues; i+= 500) {
            promises.push(requestP(url + `/issues/all_active.json?skip=${i}&take=500`).then(function(results) {
                return JSON.parse(results.body).issues;                
            }));
        }
        return Promise.all(promises).then(function(results) {
            // results is an array of each chunk (which is itself an array) so we have an array of arrays
            // now concat all results in order
            return Array.prototype.concat.apply([], results);
        })
    });
}

xxx.getAllActiveIssues().then(function(issues) {
    // process issues here
}, function(err) {
    // process error here
})

相关问答

更多
  • WebDriver测试是端到端,黑盒子,用户界面测试。 如果您的页面依赖于外部网关,您将拥有一个服务和模型来包装该网关,以便在整个系统中使用,并且您可能已经在测试中引用了模型。 鉴于网关是时间相关的,您应该在测试中使用api层所消耗的服务,并且只需检查网关随时返回的信息是否显示在as页面上,就像您期望的那样。 您将进行单元测试以正确检查响应模型。 如您所愿,强制性的“这可能是不可能的”:鉴于您的网关所受到的变化程度,您可能需要降低准确性或在测试中引入某种形式的刷新,因为这两个呼叫将到达稍微分开。 考虑到不可 ...
  • .forEach方法包含一个索引,因此您可以使用它来填充TheCurrentPrice : Contracts.forEach(function (Contract, index) { Contract.Price(function (error, result) { TheCurrentPrice[index] = result; }); }); 但请注意,您仍然需要某种形式的同步来告诉您何时已获得所有价格。 因此,更好的解决方案可能是将Price的调用Price为 ...
  • 简短的回答 - 您的哈姆雷特示例实际上正在解决一条街道: 地图链接 回答你的一般问题(猜测你在其他地方发生了这种情况,而不是街道),这是如何判断地理编码API如何确定部分匹配。 如果你得到一条路线,它应该意味着你已经返回了一条街道(有或没有号码)。 哈姆雷特应该显示为一个sublocality或neighborhood如果不是它自己的地方(在加拿大这是我所见过的): 邻里 sublocality *请注意,这些在加拿大不是有效的邮寄地址,这使我的示例与您指定的标准略有不同。 要知道路由是完全匹配还是猜测是状 ...
  • 无论您创建URL对象的顺序如何,对同一服务器的所有请求都将被流水线化,您无法控制下载顺序。此外,某些URL可能会被缓存,而其他URL可能需要转到远程服务器。 您需要做的是维护一个包含实际数据映射URL的可变数组或字典,然后等待所有URL完全下载,然后按已知顺序迭代。 You cannot control the download order in the sense that all the requests to the same server will be pipelined no matter wh ...
  • 摆脱setRequestHeader var req = new XMLHttpRequest(); var payload = {location: null, temperature:null, humidity:null}; req.open("GET", "http://api.openweathermap.org/data/2.5/weather?q=02143,us&appid=fa7d80c48643dfadde2cced1b1be6ca1", true); //req ...
  • 当我将其注销时,为什么我的问题变量为空? 有明显的结果与它相结合。 这里的一个主要问题是.concat()返回一个新数组。 它不会将项添加到现有阵列上。 你可以改变这个: issues.concat(JSON.parse(body).issues); 对此: issues = issues.concat(JSON.parse(body).issues); 确保保留新的连锁数组。 这是一个非常常见的错误。 您也可能在数组中遇到排序问题,因为您正在运行for循环,它会同时启动一大堆请求,结果可能会或可能不会 ...
  • 在仔细阅读了异步示例之后,我现在看到它重复读取,直到遇到成功读取0字节为止。 所以要回答我自己的问题,你必须一遍又一遍地调用InternetReadFile(),并为同步或异步响应做好准备。 After a more careful reading of the asynchronous example, I see now that it is reading repeatedly until a successful read of 0 bytes is encountered. So to answe ...
  • 第一种行为使用状态代码200,第二种行为使用206是否可以接受? 不,这是不可接受的。 206 Partial Content是响应对来自完整响应的某些特定字节范围的显式请求而给出的状态。 如第10.2.7节所述 : 该请求必须包含一个Range标题字段( 第14.35节 ),表示所需的范围 在您的情况下,“未经身份验证的请求” 本身不会包含Range标头,因此206响应将违反规范。 Is it acceptable to use a status code of 200 for the first beh ...
  • 请改用URLOpenPullStream 。 Use URLOpenPullStream instead.
  • 在处理异步协议时,通常需要设计协议,以便每个请求都有一个唯一的ID,该ID包含在请求数据中并在响应中发回。 这样,您可以不按顺序接收响应,甚至收到未经请求的消息。 发送请求时,将请求ID放在某个列表中,以及响应到达时将调用的回调。 当您获得数据事件时,将原始数据附加到缓冲区,然后仅从缓冲区中解析出完整的消息,留下不完整的消息以便以后完成。 对于解析出的每个完整消息,检查它是否具有请求ID。 如果不是,则消息是未经请求的,因此请相应地处理。 否则,在列表中查找请求ID,如果找到,则调用与之关联的回调。 Whe ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)