Js - однопоточная.
Браузер можно разделить на три части:
1) Event Loop
2 ) Web API
3) Очередь событий
Событие Loop запускается вечно, т. Е. Тип бесконечного цикла. Очередь ожидания - это то, где вся ваша функция нажимается на какое-либо событие (пример: нажмите) this один за другим выполняется в очереди и помещается в цикл «Событие», который выполняет эту функцию и подготавливает ее для следующего после первого запуска. Это означает, что выполнение одной функции не начинается до тех пор, пока функция, перед которой она в очереди не будет выполнена цикл событий.
Теперь давайте подумаем, что мы поставили две функции в очереди, чтобы получить данные с сервера, а другой использует эти данные. Мы сначала нажали функцию serverRequest () в очереди, а затем применили функцию Data () , Функция serverRequest переходит в цикл событий и делает вызов на сервер, так как мы никогда не знаем, сколько времени потребуется для получения данных с сервера, поэтому ожидается, что этот процесс займет много времени, и поэтому мы заняли наш цикл событий, тем самым повесив нашу страницу, вот где Web API входит в эту роль, он принимает эту функцию из цикла событий и обращается к серверу, создающему цикл событий, так что мы можем выполнить следующую функцию из очереди. Следующая функция в очереди - useData (), которая идет в цикле, но из-за отсутствия данных отходы и выполнение следующей функции продолжаются до конца очереди (это называется Async-вызовом, то есть мы можем сделать что-то еще, пока не получим данные)
Предположим, что наша функция serverRequest () имела оператор возврата в код, когда мы возвращаем данные с сервера Web API, будет выталкивать его в очередь в конце очереди. По мере того, как он заканчивается в очереди, мы не можем использовать его данные, поскольку в нашей очереди нет функции, чтобы использовать эти данные. Таким образом, невозможно вернуть что-то из Async Call.
Таким образом, решение этой проблемы callback или обещают .
A Изображение из одного из ответов здесь, правильно объясняет использование обратного вызова ... Мы (функция, использующая данные, возвращаемые с сервера), чтобы вызвать вызывающий сервер.
function doAjax(callbackFunc, method, url) { var xmlHttpReq = new XMLHttpRequest(); xmlHttpReq.open(method, url); xmlHttpReq.onreadystatechange = function() { if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200) { callbackFunc(xmlHttpReq.responseText); } } xmlHttpReq.send(null); }
В моем коде он называется
function loadMyJson(categoryValue){ if(categoryValue==="veg") doAjax(print,"GET","http://localhost:3004/vegetables"); else if(categoryValue==="fruits") doAjax(print,"GET","http://localhost:3004/fruits"); else console.log("Data not found"); }
Прочитайте здесь новые методы в ECMA (2016/17) для создания асинхронного вызова (@Felix Kling Answer сверху) https://stackoverflow.com/a/14220323/7579856
Я просто подумал, что я упомянул кое-что здесь, с которым мне пришлось долго экспериментировать, прежде чем я наконец понял, что происходит. Это может быть настолько очевидным для всех здесь, что они не удосужились упомянуть об этом. Но это помогло бы мне, если бы у них было, поэтому по этому принципу ...!
NB: Я использую Jython , в частности, v 2.7, так что, возможно, это может не быть примените к CPython ...
NB2: первые две строки моего .py-файла здесь:
# -*- coding: utf-8 -*-
from __future__ import print_function
«%» (AKA «механизм интерполяции») механизм построения строки также вызывает ДОПОЛНИТЕЛЬНЫЕ проблемы ... Если кодировка по умолчанию «среда» - это ASCII, и вы пытаетесь сделать что-то вроде
print( "bonjour, %s" % "fréd" ) # Call this "print A"
. Вам не составит труда работать в Eclipse ... В окне Windows CLI (DOS) вы обнаружите, что кодировка - это кодовая страница 850 (моя ОС Windows 7) или что-то подобное, что, по крайней мере, может обрабатывать символы с акцентом в Европе. он будет работать.
print( u"bonjour, %s" % "fréd" ) # Call this "print B"
также будет работать.
Если OTOH вы направляете файл из CLI, то стандартная кодировка будет None, которая по умолчанию будет ASCII (на моей ОС в любом случае), который не сможет обрабатывать ни одну из вышеприведенных распечаток ... (ужасная ошибка кодирования).
Итак, вы можете подумайте о перенаправлении своего stdout с помощью
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
и попробуйте запустить в конвейере CLI файл ... Очень странно, что печать A выше будет работать ... Но печать B выше выкинет ошибку кодирования ! Далее будет выполнено следующее:
print( u"bonjour, " + "fréd" ) # Call this "print C"
Вывод, к которому я пришел (временно), состоит в том, что если строка, указанная как строка Unicode , использующая «u префикс отправлен в механизм% -handling, который, как представляется, предполагает использование кодировки среды по умолчанию, независимо от того, было ли вы настроено перенаправление stdout!
Как люди справляются с этим, это вопрос выбора. Я хотел бы приветствовать эксперта Unicode, чтобы сказать, почему это происходит, независимо от того, было ли у меня это неправильное в некотором роде, какое предпочтительное решение для этого, относится ли оно также к CPython , происходит ли это в Python 3 и т. д. и т. д.
На Ubuntu 12.10 и терминале GNOME ошибка не возникает, когда программа печатает на stdout или подключается к каналу для других программ. И кодирование файлов, и терминальное кодирование - UTF-8 .
$ cat a.py
# -*- coding: utf-8 -*-
print "åäö"
$ python a.py
åäö
$ python a.py | tee out
åäö
Какую ОС и эмулятор терминала вы используете? Я слышал, что некоторые из моих коллег сталкиваются с подобными проблемами при использовании iTerm & nbsp; 2 и OS X; iTerm & nbsp; 2 может быть виновником.
Обновление: этот ответ неверен - подробнее см. комментарии
Вы можете попробовать изменить переменную окружения «PYTHONIOENCODING» на «utf_8». .
Tl; dr сообщения в блоге:
import sys, locale, os
print(sys.stdout.encoding)
print(sys.stdout.isatty())
print(locale.getpreferredencoding())
print(sys.getfilesystemencoding())
print(os.environ["PYTHONIOENCODING"])
print(chr(246), chr(9786), chr(9787))
дает вам
utf_8
False
ANSI_X3.4-1968
ascii
utf_8
ö ☺ ☻
Я столкнулся с этой проблемой в устаревшем приложении, и было трудно определить, где было напечатано. Я помог себе с этим взломом:
# encoding_utf8.py
import codecs
import builtins
def print_utf8(text, **kwargs):
print(str(text).encode('utf-8'), **kwargs)
def print_utf8(fn):
def print_fn(*args, **kwargs):
return fn(str(*args).encode('utf-8'), **kwargs)
return print_fn
builtins.print = print_utf8(print)
В верхней части моего скрипта test.py:
import encoding_utf8
string = 'Axwell Λ Ingrosso'
print(string)
Обратите внимание, что это изменяет ВСЕ вызовы на печать, чтобы использовать кодировку, поэтому ваша консоль будет печатать это:
$ python test.py
b'Axwell \xce\x9b Ingrosso'
У меня была аналогичная проблема на прошлой неделе . Это было легко исправить в моей IDE (PyCharm).
Вот мое исправление:
Начиная с панели меню PyCharm: Файл -> Настройки ... -> Редактор -> Файл Кодировки, а затем установите: «Кодирование IDE», «Кодирование проекта» и «Кодировка по умолчанию для файлов свойств» ALL для UTF-8, и теперь она работает как прелесть.
Надеюсь, что это поможет!
Во-первых, в отношении этого решения:
# -*- coding: utf-8 -*-
print u"åäö".encode('utf-8')
Невозможно явно печатать с данной кодировкой каждый раз. Это будет повторяющимся и подверженным ошибкам.
Лучшим решением является изменение sys.stdout
в начале вашей программы для кодирования с выбранной кодировкой. Вот одно из решений, которое я нашел на Python: Как выбрано sys.stdout.encoding? , в частности комментарий «toka»:
import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
Я мог бы «автоматизировать» его с помощью вызова:
def __fix_io_encoding(last_resort_default='UTF-8'):
import sys
if [x for x in (sys.stdin,sys.stdout,sys.stderr) if x.encoding is None] :
import os
defEnc = None
if defEnc is None :
try:
import locale
defEnc = locale.getpreferredencoding()
except: pass
if defEnc is None :
try: defEnc = sys.getfilesystemencoding()
except: pass
if defEnc is None :
try: defEnc = sys.stdin.encoding
except: pass
if defEnc is None :
defEnc = last_resort_default
os.environ['PYTHONIOENCODING'] = os.environ.get("PYTHONIOENCODING",defEnc)
os.execvpe(sys.argv[0],sys.argv,os.environ)
__fix_io_encoding() ; del __fix_io_encoding
Да, здесь можно получить бесконечный цикл, если этот «setenv» терпит неудачу.
export PYTHONIOENCODING=utf-8
выполняет задание, но не может установить его на самом python ...
то, что мы можем сделать, это проверить, не задано ли значение и сообщить пользователю установить его перед вызовом сценария с:
if __name__ == '__main__':
if (sys.stdout.encoding is None):
print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
exit(1)
Обновить для ответа на комментарий: проблема существует только при переходе на стандартный вывод. Я тестировал в Fedora 25 Python 2.7.13
python --version
Python 2.7.13
cat b.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
print sys.stdout.encoding
работает ./b.py
UTF-8
работает ./b.py | меньше
None
Доказанная санированная версия ответа Крейга МакКуина.
import sys, codecs
class EncodedOut:
def __init__(self, enc):
self.enc = enc
self.stdout = sys.stdout
def __enter__(self):
if sys.stdout.encoding is None:
w = codecs.getwriter(self.enc)
sys.stdout = w(sys.stdout)
def __exit__(self, exc_ty, exc_val, tb):
sys.stdout = self.stdout
Использование:
with EncodedOut('utf-8'):
print u'ÅÄÖåäö'