您不能混合 async void
和 backgroundworker.dowork
,因为一旦您击中第一个等待
, dowork 处理程序已向工人出现。
我建议您完全删除 backgroundworker
,只需使用等待
即可。
示例代码似乎缺少信息:什么是 pings
count
和文件
?我试图猜测它是如何工作的,但是看来您正在为这些使用某种缓存字段,至少在 file
的情况下)可能是不可接受的。
SemaphoreSlim _sem = new SemaphoreSlim(1, 1);
private void Ping_Btn_Click(object sender, EventArgs e)
{
if (!await _sem.WaitAsync(0)) // bail-out if already executing
return;
try
{
int counter = 1;
// For every ping object
foreach (Ping pinger in pings)
{
// Set the appropriate UI element properties
// Create initial control object
// Finds controls in which their name matches the string
(this.Controls.Find("greenBox" + counter, true).FirstOrDefault() as Control)?.Visible = false;
(this.Controls.Find("orangeBox" + counter, true).FirstOrDefault() as Control)?.Visible = false;
(this.Controls.Find("redBox" + counter, true).FirstOrDefault() as Control)?.Visible = true;
(this.Controls.Find("status_Lbl" + counter, true).FirstOrDefault() as Control)?.Text = "Initiated...";
counter++;
}
// Take input from text box
count = Convert.ToInt32(pingSeconds_TxtBox.Text);
// Start operation
await DoPing();
}
finally
{
// release lock
_sem.Release();
}
}
private async Task DoPing()
{
try
{
// Write to log file
await file.WriteAsync("Starting job...\n");
await file.WriteAsync("Requested amount of pings: " + count + "\n");
// Create date object for logs
DateTime localDate = DateTime.Now;
using (System.Net.NetworkInformation.Ping pinger = new System.Net.NetworkInformation.Ping())
{
for (int i = 0; i < count; i++)
{
foreach (Ping pingObj in pings)
{
try
{
var pingReply = await pinger.SendAsync(pingObj.IpAddress);
// Write log file
await file.WriteLineAsync(localDate.TimeOfDay + " | Friendly Name " + pingObj.FriendlyName + " | Ping: " + pingReply.Address + " | Status " + pingReply.Status + " | Time: " + pingReply.RoundtripTime);
if (pingReply.Status == IPStatus.Success)
{
pingObj.SuccessfulPings += 1;
}
else // Unsuccessful ping has been sent
{
pingObj.FailedPings += 1;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
await Task.Delay(1000);
}
}
}
catch (Exception a)
{
Debug.WriteLine(a.ToString());
}
}
当 soup.find
找不到任何东西时,它将返回无
。在中拨打 s.find_all
如果S:或 not none:
。
因此,您的代码变为:
r = requests.get('https://www.marketsandmarkets.com/Market-Reports/rocket-missile-market-203298804.html/')
soup = BeautifulSoup(r.content, 'html.parser')
s = soup.find('div', class_='entry-content')
if s is not None:
content = s.find_all('p')
print(content)
else:
print("Didn't find what I was looking for...")
或也许:
content = s.find_all('p') if s is not None else []
print(content)
awk '
NR==1{
printf "%-16s | %-9s | %s\n", "Date","Weekday","Shift"; next
}
{
"date -d \"" $0 "\" \"+%d-%m-%Y %H:%M | %A\"" | getline d
gsub(/:/, "", $2); t=int($2)
printf "%-28s | %s\n", d ,(t > 73000 && t < 193000) ? "Morning" : "Night"
}' file.csv
Date | Weekday | Shift
09-06-2022 22:30 | Thursday | Night
10-06-2022 15:55 | Friday | Morning
11-06-2022 00:34 | Saturday | Night
11-06-2022 19:51 | Saturday | Night
13-06-2022 11:34 | Monday | Morning
15-06-2022 03:59 | Wednesday | Night
18-06-2022 16:13 | Saturday | Morning
19-06-2022 00:24 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
这是你想要的吗?
data(iris)
library(ggplot2)
ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(color=Species, shape=Species)) +
xlab("Sepal Length") + ylab("Sepal Width") +
ggtitle("Sepal Length-Width") +
facet_wrap(~Species)+
geom_label(data = data.frame(x = 6, y = 5, Species = "setosa",
label = "this is interesting\nwhat now"),
aes(x = x, y = y, label = label), size = 4)
您是否有要订阅可观察到的特定原因?
如果您只需要阅读组件初始化的查询参数,请尝试以下操作:
this.route.snapshot.queryparammap.get('param')
该问题(与结果构建者有关)是在Swift 5.8中固定的。根据
这是5.7中的一个错误,以前汇编并影响了编译时间性能。我已经在论坛帖子中概述了这个问题 - https://forums.swift.org/t/impreved-result-builder-implementation-in-swift-5-8/63192 “结构诊断”子段。
有很多方法:
HTML代码:
<a id="b1" class="btnClick" type="button">B1M</a>
<a id="b2" class="btnClick" type="button">B2M</a>
一个是:
您可以在Selector jQuery中添加多个ID。
var b1 = $("#b1"), b2 = $("#b2");
b1.add(b2).click(function(){
alert('clicked', this.id)
})
这是链接: fiddle
另一个是:
您可以将同一类给所有标签
jQuery代码:
$(".btnClick").click(function(){
alert('clicked', this.id)
})
这是另一个链接: fiddle
您不应具有通过 QuizQuestions
数组进行迭代的循环。此功能应仅处理 QuizQuestions [CurrentQuestion]
。当用户转到下一个问题而不是此功能时,应递增 CurrentQuestion
索引。
var questionOne = function() {
// create container to hold questions and answer options & give it a class name
var questionsDiv = document.createElement("div");
questionsDiv.className = "questions-div";
// create question stem, give it a class name, add its content, & append to questionsDiv
var questionStem = document.createElement("h2");
questionStem.className = "question-stem";
questionStem.innerText = quizQuestions[currentQuestion].question;
questionsDiv.append(questionStem);
// create container to hold answer option buttons
var answerOptionsDiv = document.createElement("div");
// create footer container, give it a class name, & append to the questionsContainer
var footerDiv = document.createElement("div");
footerDiv.className = "footer-div";
questionsContainer.append(footerDiv);
// create footer text (correct/wrong), give it a class name, & append to footerDiv
var footerTextCorrect = document.createElement("h2");
footerTextCorrect.className = "footer-text-correct";
footerTextCorrect.innerText = "Correct!";
footerDiv.append(footerTextCorrect);
var footerTextWrong = document.createElement("h2");
footerTextWrong.className = "footer-text-wrong";
footerTextWrong.innerText = "Wrong!";
footerDiv.append(footerTextWrong);
// append questionsDiv to main questions container
questionsContainer.append(questionsDiv);
// append answerOptionsDiv to questions container
questionsDiv.append(answerOptionsDiv);
console.log(quizQuestions[currentQuestion].question);
for (let j = 1; j <= 4; j++) {
console.log(`${j}. ${quizQuestions[currentQuestion].options[`${j}`]}`);
// create buttons for answer options and add their content
var optionBtnOne = document.createElement("button");
optionBtnOne.innerText = `${j}. ${
quizQuestions[currentQuestion].options[`${j}`]
}`;
// append button to answerOptionsDiv
answerOptionsDiv.append(optionBtnOne);
optionBtnOne.addEventListener("click", selectAnswer);
optionBtnOne.setAttribute(
"id",
`${quizQuestions[currentQuestion].options[`${j}`]}`
);
}
};
运行 Expo Start
,您应该很好!遇到了同一问题,这解决了它。
接受的答案不是一个很好的一般解决方案,它不会限制小数点的数量,它只是切断了可能是在小数后可能或不可能的字符。
正确的答案是使用 tofixed
,例如Mel Carlo Iguis的答案。您可以在设置状态之前每次调用 tofixed
:
setNum(Number(newValue.toFixed(1))) // 1 for 1 decimal place, adjust as needed
尽管该方法丢失了信息 - 如果要保留 num
高精度以进行将来的计算,则可以使用在实际渲染步骤中tofixed
。 这是我建议的模式:
<div> {num.toFixed(1)} </div>
对于第一种情况,
这是.htacess的代码
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^ http://www.example1.com%{REQUEST_URI} [L,NE,P]
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, ProductCategory VARCHAR(30), _year CHAR(4));
INSERT INTO @tbl (ProductCategory, _year) VALUES
('Toys', '2008'),
('Footwear', '2008'),
('Cookware', '2008'),
('Toys', '2009'),
('Toys', '2007'),
('Footwear', '2009'),
('Footwear', '2007'),
('Clothes', '2008');
-- DDL and sample data population, end
;WITH rs AS
(
SELECT *
, total_count = COUNT(*) OVER (PARTITION BY ProductCategory ORDER BY ProductCategory)
, _2008_count = SUM(IIF (_year='2008', 1, 0)) OVER (PARTITION BY ProductCategory ORDER BY ProductCategory)
FROM @tbl
)
SELECT ID, ProductCategory, _year
FROM rs
WHERE total_count <> _2008_count
ORDER BY ID;
输出
+----+-----------------+-------+
| ID | ProductCategory | _year |
+----+-----------------+-------+
| 1 | Toys | 2008 |
| 2 | Footwear | 2008 |
| 4 | Toys | 2009 |
| 5 | Toys | 2007 |
| 6 | Footwear | 2009 |
| 7 | Footwear | 2007 |
+----+-----------------+-------+
UTF-8中有两种不同的强调字符表示,并分解了。
- 组成的表示形式使用单个编码点,
é
\ u00e9
\ code> \ xc3 \ xa9
- 分解表示形式使用两个codepoints,base glyph
e e 的组合标记
\ u0065
\ x65
以及Accent \ u0301
\ xcc \ xcc \ x81
也就是说,在使用UTF-8的文件名接受文件名时,您应该在将这些名称写入磁盘和/或创建链接之前,以避免此问题,以避免此问题和其他问题。
要归一化为组成和分解的表格:
$input = "e\xCC\x81";
$norm_c = Normalizer::normalize($input, Normalizer::FORM_C);
$norm_d = Normalizer::normalize($input, Normalizer::FORM_D);
var_dump(
$input, bin2hex($input),
$norm_c, bin2hex($norm_c),
$norm_d, bin2hex($norm_d)
);
输出:
string(3) "é"
string(6) "65cc81"
string(2) "é"
string(4) "c3a9"
string(3) "é"
string(6) "65cc81"
您还应检查OS和文件系统如何处理UTF-8文件名。有些人只会将任何系列字节写为文件名,有些会很挑剔和拒绝,而另一些字节将执行自己的标准化,而这些标准化可能并不符合您在应用程序中选择的内容。
a in
这是一个类比,希望能使同步和异步流更清晰地之间有所不同:
同步
想象您打电话给朋友,并要求他为您寻找东西。尽管可能需要一段时间,但您在电话上等待太空,直到您的朋友给您所需的答案。
当您进行包含“正常”代码的函数调用时,也会发生同样的情况:
即使
FindItem
可能需要很长时间才能执行,var item = var item = findItem(); 必须等待,直到函数返回结果。
异步
出于同样的原因, 您再次致电您的朋友。但是这次您告诉他您很着急,他应该在手机上给您回电。您挂断电话,离开房子,做您计划做的任何事情。一旦您的朋友给您回电,您就会处理他给您的信息。
这就是您执行AJAX请求时发生的事情。
执行并没有等待响应,而是立即继续执行,并且执行AJAX调用后的语句。为了最终获得响应,您提供了一个函数,一旦收到响应,a challback (请注意某件事?回电?)。在调用回调之前执行该呼叫后的任何语句。
解决方案
包含JavaScript!的异步性质,而某些异步操作提供同步的对应物(“ Ajax”也是如此),通常不愿意使用它们,尤其是在浏览器上下文中。
你为什么问不好?
JavaScript在浏览器的UI线程中运行,任何长期运行的过程都会锁定UI,从而使其无反应。此外,JavaScript的执行时间有一个上限,浏览器将询问用户是否继续执行。
所有这些都导致了非常糟糕的用户体验。用户将无法分辨出一切工作正常。此外,对于连接缓慢的用户而言,效果会更糟。
在以下内容中,我们将查看三种彼此之间建立的不同解决方案:
ynnc/等待
(ES2017++,如果您使用的话,可在较旧的浏览器中使用transpiler或recenener)then()
(ES2015+)承诺(ES2015+)浏览器如果使用众多承诺库之一)所有三个都在当前浏览器中可用,节点7+。
es2017+:promise
async/等待
2017年在2017年发布的ecmascript版本引入了 andtax-level support syynChronionus函数。借助
async
和等待
,您可以以“同步样式”编写异步。该代码仍然具有异步,但是阅读/理解更容易。异步/等待
在承诺之上构建:async
函数始终返回承诺。等待
“取消包裹”的承诺,并且如果拒绝承诺,则可以解决承诺的价值或丢弃错误。重要:您只能在
async
函数或 en-us/doc/web/javaScript/guide/模块“ rel =“ noreferrer”> javascript模块。顶级等待
在模块之外不支持,因此您可能必须制作一个异步(立即调用函数表达式)启动async
上下文如果不使用模块。您可以阅读有关 noreferrer“>
async
和等待MDN上。
这是详细列出 delay 函数
finditem()
上面的示例:当前浏览器和 node 版本支持
async/aync/negait
。您还可以在 recenererator 的帮助下,通过将代码转换为ES5来支持旧环境。 ,例如 babel )。让函数接受回调
一个回调是当函数1传递给函数2时。函数2可以在准备就绪时调用函数1。在异步过程的上下文中,每当完成异步过程时,都会调用回调。通常,结果将传递给回调。
在问题的示例中,您可以进行
foo
接受回调,并将其用作Success
回调。因此,这将成为
这里定义“内联”函数,但是您可以传递任何函数参考:
foo
本身定义如下:callback
将参考我们传递给<<<的函数。代码> foo 我们调用它,然后将其传递给Success
。即,一旦AJAX请求成功,$。ajax
将调用回调
,然后将响应传递给回调(可以使用result> Result
来参考。 ,因为这就是我们定义回调的方式)。您还可以在将响应传递给回调之前处理:
使用回调编写代码比看起来更容易。毕竟,浏览器中的JavaScript是事件驱动的(DOM事件)。接收Ajax响应只是事件。
当您必须使用第三方代码时,可能会出现困难,但是只要考虑应用程序流程,就可以解决大多数问题。
ES2015+: the
一个href =“ https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_object/global_objects/promise” rel =“ noreferrer”> Promise api ),但是它有很好的浏览器支持。也有许多库可以实现标准承诺API并提供其他方法来减轻异步功能的使用和组成(例如,)。
承诺是未来值的容器。当承诺收到值(已解决的)或取消(拒绝)时,它会通知所有想访问此值的“听众”。
比普通回调的优势在于,它们允许您将代码解除,并且更容易撰写。
这是使用承诺的示例:
应用于我们的Ajax电话,我们可以使用这样的承诺:
描述承诺提供的所有优势超出了此答案的范围,但是如果您编写新代码,则应认真考虑它们。它们提供了很好的抽象和您的代码分离。
有关承诺的更多信息: html5 rocks -javascript Promises promises 。
旁注:jQuery的延期对象
延迟对象标准化)。他们的行为几乎像承诺,但暴露了略有不同的API。
jQuery的每种AJAX方法已经返回一个“递延对象”(实际上是递延对象的承诺),您可以从函数中返回:
侧面注意:promise gotchas new Chep
牢记承诺和递延对象只是容器 /em>对于未来的价值,它们不是价值本身。例如,假设您有以下内容:
此代码误解了上述异步问题。具体来说,
$。ajax()
在检查服务器上的“/密码”页面时不会冻结代码 - 它将请求发送到服务器,并且在等待时,它立即返回jQuery AJAX递延对象,而不是服务器的响应。这意味着如果
语句将始终获取此延期对象,请将其视为true
,然后继续以用户登录。不好。但是修复程序很容易:
不推荐:我提到的同步“ ajax”调用
,一些(!)异步操作具有同步的对应物。我不主张他们的使用,但为了完整的缘故,这是您执行同步呼叫的方式:
如果
直接使用
xmlhttprequest
对象,将false
作为第三个参数作为.open
。jQuery
如果您使用 jquery ,您可以设置
async
选项false
。请注意,由于jQuery 1.8,此选项是弃用。然后,您可以仍然使用
成功
回调,或访问ResponseText
jqxhr对象:如果您使用任何其他jquery ajax方法,例如
$。get
,$。getjson
等。 。抬头!无法同步 jsonp 请求。 JSONP本质上总是异步的(甚至不考虑此选项的另一个原因)。
The problem
The A in Ajax stands for asynchronous. That means sending the request (or rather receiving the response) is taken out of the normal execution flow. In your example,
$.ajax
returns immediately and the next statement,return result;
, is executed before the function you passed assuccess
callback was even called.Here is an analogy which hopefully makes the difference between synchronous and asynchronous flow clearer:
Synchronous
Imagine you make a phone call to a friend and ask him to look something up for you. Although it might take a while, you wait on the phone and stare into space, until your friend gives you the answer that you needed.
The same is happening when you make a function call containing "normal" code:
Even though
findItem
might take a long time to execute, any code coming aftervar item = findItem();
has to wait until the function returns the result.Asynchronous
You call your friend again for the same reason. But this time you tell him that you are in a hurry and he should call you back on your mobile phone. You hang up, leave the house, and do whatever you planned to do. Once your friend calls you back, you are dealing with the information he gave to you.
That's exactly what's happening when you do an Ajax request.
Instead of waiting for the response, the execution continues immediately and the statement after the Ajax call is executed. To get the response eventually, you provide a function to be called once the response was received, a callback (notice something? call back ?). Any statement coming after that call is executed before the callback is called.
Solution(s)
Embrace the asynchronous nature of JavaScript! While certain asynchronous operations provide synchronous counterparts (so does "Ajax"), it's generally discouraged to use them, especially in a browser context.
Why is it bad do you ask?
JavaScript runs in the UI thread of the browser and any long-running process will lock the UI, making it unresponsive. Additionally, there is an upper limit on the execution time for JavaScript and the browser will ask the user whether to continue the execution or not.
All of this results in a really bad user experience. The user won't be able to tell whether everything is working fine or not. Furthermore, the effect will be worse for users with a slow connection.
In the following we will look at three different solutions that are all building on top of each other:
async/await
(ES2017+, available in older browsers if you use a transpiler or regenerator)then()
(ES2015+, available in older browsers if you use one of the many promise libraries)All three are available in current browsers, and node 7+.
ES2017+: Promises with
async/await
The ECMAScript version released in 2017 introduced syntax-level support for asynchronous functions. With the help of
async
andawait
, you can write asynchronous in a "synchronous style". The code is still asynchronous, but it's easier to read/understand.async/await
builds on top of promises: anasync
function always returns a promise.await
"unwraps" a promise and either result in the value the promise was resolved with or throws an error if the promise was rejected.Important: You can only use
await
inside anasync
function or in a JavaScript module. Top-levelawait
is not supported outside of modules, so you might have to make an async IIFE (Immediately Invoked Function Expression) to start anasync
context if not using a module.You can read more about
async
andawait
on MDN.Here is an example that elaborates the delay function
findItem()
above:Current browser and node versions support
async/await
. You can also support older environments by transforming your code to ES5 with the help of regenerator (or tools that use regenerator, such as Babel).Let functions accept callbacks
A callback is when function 1 is passed to function 2. Function 2 can call function 1 whenever it is ready. In the context of an asynchronous process, the callback will be called whenever the asynchronous process is done. Usually, the result is passed to the callback.
In the example of the question, you can make
foo
accept a callback and use it assuccess
callback. So thisbecomes
Here we defined the function "inline" but you can pass any function reference:
foo
itself is defined as follows:callback
will refer to the function we pass tofoo
when we call it and we pass it on tosuccess
. I.e. once the Ajax request is successful,$.ajax
will callcallback
and pass the response to the callback (which can be referred to withresult
, since this is how we defined the callback).You can also process the response before passing it to the callback:
It's easier to write code using callbacks than it may seem. After all, JavaScript in the browser is heavily event-driven (DOM events). Receiving the Ajax response is nothing else but an event.
Difficulties could arise when you have to work with third-party code, but most problems can be solved by just thinking through the application flow.
ES2015+: Promises with then()
The Promise API is a new feature of ECMAScript 6 (ES2015), but it has good browser support already. There are also many libraries which implement the standard Promises API and provide additional methods to ease the use and composition of asynchronous functions (e.g., bluebird).
Promises are containers for future values. When the promise receives the value (it is resolved) or when it is canceled (rejected), it notifies all of its "listeners" who want to access this value.
The advantage over plain callbacks is that they allow you to decouple your code and they are easier to compose.
Here is an example of using a promise:
Applied to our Ajax call we could use promises like this:
Describing all the advantages that promise offer is beyond the scope of this answer, but if you write new code, you should seriously consider them. They provide a great abstraction and separation of your code.
More information about promises: HTML5 rocks - JavaScript Promises.
Side note: jQuery's deferred objects
Deferred objects are jQuery's custom implementation of promises (before the Promise API was standardized). They behave almost like promises but expose a slightly different API.
Every Ajax method of jQuery already returns a "deferred object" (actually a promise of a deferred object) which you can just return from your function:
Side note: Promise gotchas
Keep in mind that promises and deferred objects are just containers for a future value, they are not the value itself. For example, suppose you had the following:
This code misunderstands the above asynchronous issues. Specifically,
$.ajax()
doesn't freeze the code while it checks the '/password' page on your server - it sends a request to the server and while it waits, it immediately returns a jQuery Ajax Deferred object, not the response from the server. That means theif
statement is going to always get this Deferred object, treat it astrue
, and proceed as though the user is logged in. Not good.But the fix is easy:
Not recommended: Synchronous "Ajax" calls
As I mentioned, some(!) asynchronous operations have synchronous counterparts. I don't advocate their use, but for completeness' sake, here is how you would perform a synchronous call:
Without jQuery
If you directly use a
XMLHttpRequest
object, passfalse
as third argument to.open
.jQuery
If you use jQuery, you can set the
async
option tofalse
. Note that this option is deprecated since jQuery 1.8.You can then either still use a
success
callback or access theresponseText
property of the jqXHR object:If you use any other jQuery Ajax method, such as
$.get
,$.getJSON
, etc., you have to change it to$.ajax
(since you can only pass configuration parameters to$.ajax
).Heads up! It is not possible to make a synchronous JSONP request. JSONP by its very nature is always asynchronous (one more reason to not even consider this option).
如何从异步电话中返回响应?