Вместо того, чтобы бросать код на вас, есть два понятия, которые являются ключом к пониманию того, как JS обрабатывает обратные вызовы и асинхронность. (это даже слово?)
Есть три вещи, о которых вам нужно знать; Очередь; цикл события и стек
. В широких упрощенных терминах цикл событий подобен диспетчеру проекта, он постоянно прослушивает любые функции, которые хотят запускать и взаимодействовать между очереди и стека.
while (queue.waitForMessage()) {
queue.processNextMessage();
}
Как только он получает сообщение для запуска чего-то, он добавляет его в очередь. Очередь - это список вещей, которые ждут выполнения (например, ваш запрос AJAX). Представьте себе это так:
1. call foo.com/api/bar using foobarFunc
2. Go perform an infinite loop
... and so on
Когда одно из этих сообщений будет исполнено, оно выталкивает сообщение из очереди и создает стек, стек - это все, что нужно выполнить JS для выполнения инструкции в сообщение. Таким образом, в нашем примере ему говорят позвонить foobarFunc
function foobarFunc (var) {
console.log(anotherFunction(var));
}
. Так что все, что foobarFunc должно выполнить (в нашем случае anotherFunction
), будет вставлено в стек. исполняемый, а затем забытый - цикл события затем переместится на следующую вещь в очереди (или прослушивает сообщения)
. Главное здесь - порядок выполнения. Это
Когда вы совершаете вызов с использованием AJAX для внешней стороны или выполняете любой асинхронный код (например, setTimeout), Javascript зависит от ответ, прежде чем он сможет продолжить.
Большой вопрос, когда он получит ответ? Ответ в том, что мы не знаем, поэтому цикл событий ждет, когда это сообщение скажет: «Эй, забери меня». Если JS просто ждал этого сообщения синхронно, ваше приложение замерзнет, и оно сосать. Таким образом, JS продолжает выполнение следующего элемента в очереди, ожидая, пока сообщение не будет добавлено обратно в очередь.
Вот почему с асинхронной функциональностью мы используем вещи, называемые обратными вызовами. Это похоже на обещание буквально. Как и в I , обещание что-то вернуть в какой-то момент jQuery использует специальные обратные вызовы, называемые deffered.done
deffered.fail
и deffered.always
(среди других). Вы можете увидеть их все здесь
Итак, вам нужно передать функцию, которая в какой-то момент будет выполнена с переданными ей данными.
Поскольку обратный вызов не выполняется немедленно, но в более позднее время важно передать ссылку на функцию, которую она не выполнила. поэтому
function foo(bla) {
console.log(bla)
}
, поэтому большую часть времени (но не всегда) вы пройдете foo
не foo()
. Надеюсь, это будет иметь смысл. Когда вы сталкиваетесь с такими вещами, которые кажутся запутанными, я настоятельно рекомендую полностью прочитать документацию, чтобы хотя бы понять ее. Это сделает вас намного лучшим разработчиком.
Мне пришлось сделать что-то вроде
>>> import numpy as np
>>> from datetime import datetime
>>> wind = np.loadtxt("ws425.log.test", delimiter=",", usecols=(0,4), dtype=object,
... converters={0: lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S.%f"),
... 4: np.float})
>>>
>>> wind
array([[datetime.datetime(2013, 12, 11, 23, 0, 27, 3293), 5.8],
[datetime.datetime(2013, 12, 11, 23, 0, 28, 295), 5.5],
[datetime.datetime(2013, 12, 11, 23, 0, 29, 295), 4.0],
[datetime.datetime(2013, 12, 11, 23, 0, 30, 3310), 4.9]], dtype=object)
. Однако для данных временных рядов я переключился на использование pandas
, поскольку он делает многое многое другое:
>>> import pandas as pd
>>> df = pd.read_csv("ws425.log.test", parse_dates=[0], header=None, usecols=[0, 4])
>>> df
0 4
0 2013-12-11 23:00:27.003293 5.8
1 2013-12-11 23:00:28.000295 5.5
2 2013-12-11 23:00:29.000295 4.0
3 2013-12-11 23:00:30.003310 4.9
[4 rows x 2 columns]
>>> df[0][0]
Timestamp('2013-12-11 23:00:27.003293', tz=None)
Я не уверен, что не так с numpy; но с csv он отлично работает:
>>> import time
>>> import csv
>>> with open('t.txt') as f:
... r = csv.reader(f)
... w = [[time.strptime(i[0], '%Y-%m-%d %H:%M:%S.%f')]+i[1:] for i in r]
...
>>> w
[[time.struct_time(tm_year=2013, tm_mon=12, tm_mday=11, tm_hour=23, tm_min=0, tm_sec=27, tm_wday=2, tm_yday=345, tm_isdst=-1), '$PAMWV', '291', 'R', '005.8', 'M', 'A*36'], [time.struct_time(tm_year=2013, tm_mon=12, tm_mday=11, tm_hour=23, tm_min=0, tm_sec=28, tm_wday=2, tm_yday=345, tm_isdst=-1), '$PAMWV', '284', 'R', '005.5', 'M', 'A*3F'], [time.struct_time(tm_year=2013, tm_mon=12, tm_mday=11, tm_hour=23, tm_min=0, tm_sec=29, tm_wday=2, tm_yday=345, tm_isdst=-1), '$PAMWV', '273', 'R', '004.0', 'M', 'A*33'], [time.struct_time(tm_year=2013, tm_mon=12, tm_mday=11, tm_hour=23, tm_min=0, tm_sec=30, tm_wday=2, tm_yday=345, tm_isdst=-1), '$PAMWV', '007', 'R', '004.9', 'M', 'A*3B']]
time.strptime()
ожидает строку, такую как '2013-12-11 23:00:30.003310'
, но вы даете ей строковое представление массива:
['2013-12-12 00:00:02.251311', '2013-12-12 00:00:03.255296', ...]
Минимальное исправление заключается в анализе одного элемента за раз:
ts = [time.strptime(s, '%Y-%m-%d %H:%M:%S.%f') for s in wind[:,0]]
Или вы можете использовать параметр converters
для loadtxt
:
from datetime import datetime
import numpy as np
def str2timestamp(timestr, epoch=datetime.fromtimestamp(0)):
"""Convert local time string into seconds since epoch (float)."""
# np.datetime64 API is experimental so use datetime instead
#NOTE: local time may be ambiguous, non-monotonous
dt = datetime.strptime(timestr, '%Y-%m-%d %H:%M:%S.%f')
return (dt - epoch).total_seconds()
wind = np.loadtxt('input.csv', usecols=(0, 4), delimiter=',',
converters={0: str2timestamp})
print(wind)
[[ 1.38679203e+09 5.80000000e+00]
[ 1.38679203e+09 5.50000000e+00]
[ 1.38679203e+09 4.00000000e+00]
[ 1.38679203e+09 4.90000000e+00]]
У вас просто есть ошибки в вызове NumPy loadtxt
, где вы определяете dtype
. Это должно быть dtype=[('date', 'str', 26), ('wind', 'float')]
; вы должны указать размер строки. Теперь вы можете ссылаться на поле даты, используя свое имя, EG: wind['date']
. Ваш формат strptime
прекрасен, но вы хотите, чтобы модуль datetime
из пакета datetime
Python, а не time
.
import numpy as np
from datetime import datetime
wind = loadtxt("/disk2/Wind/ws425.log.test", dtype=[('date', 'str', 26), ('wind', 'float')], delimiter=',', usecols=(0,4))
ts = [datetime.strptime(d, '%Y-%m-%d %H:%M:%S.%f') for d in wind['date']]
Это возвращает следующее:
[datetime.datetime(2013, 12, 11, 23, 0, 27, 3293),
datetime.datetime(2013, 12, 11, 23, 0, 28, 295),
datetime.datetime(2013, 12, 11, 23, 0, 29, 295),
datetime.datetime(2013, 12, 11, 23, 0, 30, 3310)]
Возможно, вы хотите передать это обратно в ваш массив NumPy?
wind['date'] = np.array(ts, dtype='datetime64[s]')
это дает
array([('2013-12-11T23:00:27Z', 5.8), ('2013-12-11T23:00:28Z', 5.5),
('2013-12-11T23:00:29Z', 4.0), ('2013-12-11T23:00:30Z', 4.9)],
dtype=[('date', 'S26'), ('wind', '<f8')])
О, настоящая проблема заключается в том, что time.strptime не поддерживает% f для микросекунд, см. здесь для списка символов форматирования, поддерживаемых time.strptime и time .strftime.
То, что вы действительно хотите, это datetime.strptime , который поддерживает символ форматирования% f для микросекунд.