/// BANGBOO BLOG ///
■21/2/10 7:30PM
Python
おッPythonやるのか?

ファイル拡張子oppython.py デフォUTF-8、全部オブジェクト(list,dict,set等のミュータブルなら参照になる点に注意、必要ならcopy())#コメント、ドキュメントストリング(三連引用符):"""そのまま表示""" print mymod.__doc__で見れる変数型不要:p = 500 * num、でもキャストは必要、定数はない文字繰り返し、キャスト:"文字列" * 4 + str(p) + "Hi\nお元気ですか?\nSee u"raw文字列でescしない:print(r"インストール先は c:\\code\python\bin です")
 正規表現のrも同意 re_result = re.match('hel', r'hellow python, 123, end.' )
  if re_result: #None以外という意味で、Noneはいわゆるnull、Pythonにnullはない文字数:len("東京都")→3
文字列[開始:終了]→→ str = "Flower" print(str[1:4]) → low文字列 % (値1, 値2, ...)→→ num= "10進数では %d 、16進数では %x " % (num, num)
"xxxx{index:書式指定子}xxxx".format(値)→→ "名は{:<8s}で年は{:>3d}で".format(name, age)f"xxxx{値:書式指定子}xxxx"→→ f"名は{name:<8s}で年は{age:>3d}で" 0/空の文字列''/値なしはfalse、Noneは? x = None x is None→→true?//→除算切り捨てし整数、**→べき乗
関数宣言はdef kansu(): で中で宣言する変数はローカル変数
 関数外で宣言された変数はグローバル変数でどの関数の中でも扱えるようになる
 なお関数内でもglobal henでグローバル変数を宣言できる Pythonでのグローバル(global)変数の宣言方法 | UX MILK
返り値複数はcsvでタプルになる、リストが楽か? return a,b → (a, b) あるいは return [a, b] → [a, b]
def func(a, b): return a, bresult = func() result[0]がa、result[1]がbtry/exceptを関数内で設定することも、逆に関数呼び出し時にも使用ができる、else, finally, raiseも使う、エラーが出ても止めたくない場合は try-except Exceptions as e、逆にexceptを入れなければ止まるので安全try: get_all_transfer(project_id)excerpt Exception as e: print(e)置換は左辺が要る?要る a = a.replace('x','')
とほほのPython入門 - リスト・タプル・辞書 - とほほのWWW入門 (tohoho-web.com)
Pythonの辞書とリストとクラス 複数情報の受け渡し|みはみ|note
リストa=[1,2,3]はmap(), filter(), reduce()等が使える
 a=a.append()とかa=a.extend()は値がないんで駄目、単純にappend(b)やextend(b)で左辺不要
 取得:a[0]、for v in a:
 リストの合体:list_a += list_b
セット型set={1,2,3}は重複や順序や添字の無いリスト、set(list)でキャストし重複を無くせる、ミュータブルは格納できない
 取得 for v in a:
tuple→タプルは定数リスト、更新無しならリストより速い a = 1,2,3 a = (1, 2, 3)
 取得:a[0]、for num in a:dict→辞書は連想配列みたいな{a:1,b:2}はitems(), keys(), valus(), iteritems(), get()を使える
 Python | 辞書に含まれるすべてのキーと値を取得する (javadrive.jp)
 取得:dict_a['key1']、for k in dict_a.keys(): for v in dict_a.values(): for k, v in dict_a.items():
 dictの合体:dict_a.update(dict_b)
クラス→例えば●●クラスを宣言しsampleインスタンスを生成し、getter/setterで変数に入れて置く
 取得:sample.key
BigQuery→別名を付ければ名前で取得できるが、インデックスでも取得できる(これ何?)
 取得:for row in query_job: →row[0], row["t"]
lambdaは無名関数?
str_w = input('何か入力してください-->') #入力させた値を取れるが数字もstr__iter__()はnext()を持つオブジェクトを返し、next()は次の要素を返し、最後に達するとStopIteration例外を返す?yield はイテレータを返すジェネレータを定義?@デコレータは関数を実行する前後に特殊な処理を実行したい場合?withで終了処理を指定できる、ファイル読込とその後の処理とか
assertや__debug__はテストで機体通りかを確認する?
passは中身の無い関数やクラスを作成しkara.p=1で粋なり属性追加等ができる
execは引数の文字列をPythonとして実行 exec "print 'Hello'"
delはオブジェクトを削除 del x, y, z
継承やオーバーライド class MyClass2(MyClass):
多重継承class MyClassC(MyClassA, MyClassB): で纏めて使えるようになる
class MyClass:    """A simple example class"""  # 三重クォートによるコメント    def __init__(self):  # コンストラクタ        self.name = ""    def __del__(self): #インスタンスが消滅する際に呼出でコンストラクタ        print "DEL!"    def __str__(self): #文字列化        return "My name is " + self.name    def getName(self):  # getName()メソッド        return self.name    def setName(self, name):  # setName()メソッド        self.name = name
class MyClass2(MyClass):    def world(self):        print "World"class MyClass3(MyClass):    def hello(self):  # 親クラスのhello()メソッドをオーバーライド        print "HELLO"a = MyClass()  # クラスのインスタンスを生成a.setName("Tanaka")  # setName()メソッドをコールprint a.getName()    # getName()メソッドをコールprint a  #=> My name is Tanaka 文字列化b = MyClass2()  #継承b.hello()    #=> Hellob.world()    #=> Worldc = MyClass3()  #オーバーライドc.hello()    #=> HELLO
super()を使ってオーバーライドする super()は基底クラスのメソッドを継承した上で処理を拡張 super().__init__(x、y)が使えるif __name__ == "__main__": モジュール時の勝手実行を抑える  import helloの時hello.py 内部での __name__ は "hello"   python hello.pyのような実行時hello.py の内部の __name__ は "__main__"
from math import pi, radians→mathモジュールから特定のオブジェクト(関数/変数/クラス)をimpo(math.piみたいに書かず省略できる)import urllib.error→urllibパッケージからerrorモジュールをimpo、パッケージはフォルダimport numpy as np→別名でしか使えなくなるnp.array()とかで モジュール=ファイル名.pyでファイルをimpoしている
from {another_file} import {ClassName} another_file.pyがファイル名 class ClassNameがクラス名
from {パッケージ:ディレクトリ} import {モジュール:ファイル}
 ちゅー書き方もできるらしいが、どっち?impo順:標準ライブラリ>サードパーティライブラリ>ローカルライブラリ(自作のライブラリ)
関数や変数:小文字スネークケース(sample_func)クラス名、例外、型変数:キャピタルパスカルケース(SampleClass)定数名:大文字アンダースコア区切り(SAMPLE_CONST)モジュール名:小文字(samplemodule, sample_module)パッケージ(フォルダ)名:小文字。アンダースコア非推奨(samplepackage)

インデントは半角スペース4つ1行半角で79文字以内トップレベルの関数やクラスは2行開けるクラス内部では1行ずつ開けてメソッド定義
ドックストリングでクラスや関数についてコメントする(慣習的にダブルクォート)
 コード中は処理についてのコメントをなくし関数化とdocstringで参照するように
 「コメント(#)とdocstring(""")の違いは?」コメントとdocstringについて
 [Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル) - Qiita
デバッグの方法案
print(type(v)) でどんなメソッドを持っているか等を探る
print(v) をコマンド前後や流れで沢山仕込みでどこでエラーが出ているか探す
print("creds:")print(creds)print("type(creds:")print(type(creds))print("vars(creds:")print(vars(creds))print("creds.keys():")print(creds.keys())print("dir(creds):")print(dir(creds))print("creds._dict_:")print(creds.__dict__)

is not subscriptableのエラー 添字不可エラーでリストでないのにリストとして入れようとしている
※参照になりコピーされない、必要ならコピー(値を入れた時点で参照が外れるので実際問題少ない?)a = []b = ab.append(1)print(a) #[1]https://qiita.com/ponnhide/items/cda0f3f7ac88262eb31ehttps://nishiohirokazu.hatenadiary.org/entry/20120125/1327461670

環境変数を扱う
 import os print(os.environ["HOME"]) ホームディレクトリ、LANGでja_JP.UTF-8とか os.environ["PHASE"] = "staging" 環境変数に代入できるのは文字列だけ del os.environ["PHASE"] 削除コマンドラインの引数を扱う python3 sys_arg_test.py a 100
  dst_prj = sys.argv[1] (aが入っている)  sys.argv (['sys_arg_test.py','a','100']
Pythonのリストと文字列を相互に変換する方法まとめ | HEADBOOST
→リストをStrに変換してSQLにする場合For文が良い(Pythonの書式とSQL書式のコンビなので丁寧に対処するため)i = 0
v = "["
for s in list_v:    i += 1    if i > 1:        v += ","
    v += "'" + s + "'"
v += "]"SQL = "insert into aaa (aaa) value ({v})"

※テキスト選択 Shift↑or↓ で行全体 home(+fn)で行頭、end(+fn)で行末移動

【基礎一覧】Pythonの基本文法を全て解説してみた!【初心者】 (suwaru.tokyo)
Python基本文法まとめ - Qiita
とほほのPython入門 - とほほのWWW入門 (tohoho-web.com)Python入門 ~Pythonのインストール方法やPythonを使ったプログラミングの方法について解説します~ | Let'sプログラミング (javadrive.jp)
Welcome to Python.org

HTMLの中に少し埋め込めず、基本的にプログラムの中にHTMLを埋め込む:CGI(Perl然)
 さくらインターネットでPython CGI (mwsoft.jp)
WSGI Python で WSGI (Web Server Gateway Interface) に従ったシンプルな Web サーバで Hello World - Qiita
Python用Webサイト用途フレームワーク:Flask(軽量)、Django
 WSGI について — Webアプリケーションフレームワークの作り方 in Python (c-bata.link)
 GCPでどう使うかは不明だがホスティングは↓
 ウェブ ホスティング | Google Cloud 静的ウェブサイトのホスティング  |  Cloud Storage  |  Google Cloud

str.split() 区切り文字で分割しリスト等に入れる Pythonで文字列を分割(区切り文字、改行、正規表現、文字数) | note.nkmk.me
print('Sam' in 'I am Sam') # True 任意の文字列を含むか判定: in演算子 Pythonで文字列を検索(〜を含むか判定、位置取得、カウント) | note.nkmk.me
==============
ここで動かせるgoogle colaboratory→ Colaboratory へようこそ - Colaboratory (google.com)
コラボラトリはマークダウン Qiita マークダウン記法 一覧表・チートシート - Qiita
半角スペース2個で改行#の数で見出し*で箇条書き数字と.で番号を振る、- でリスト* or - or _ を3つ以上で水平線[ ]でチェックボックス、[x]でチェック| td | td | td |でテーブル**aaa**で太字、*aaa*で斜体~~aaa~~で打消し線[タイトル](URL)でリンク```でコードの挿入、`でインライン挿入> or >> で引用
 [^1]で注釈\バックスラッシュでマークダウンのエスケープ
==============
宗教論争(事実は同じでも他人の認知は違うので意味なし
if self.flag_ok == 1 and self.mode == '1'
↓一見で分からんなら変数名を工夫してこうやんな
if self.file_verify_completed and self.mode == GRANT_PERMISSION:

マジックナンバーを使わない(数字の方が曖昧性が無い場合も)STATUS_ERROR = -1STATUS_SUCCESS = 0self.status_error = STATUS_SUCCESS
with構文で処理の前後でコンテキストマネジャ__enter__、__exit__が使われる __enter__メソッドで事前処理 __exit__メソッドで事後処理with ファイル操作や通信などの開始時の前処理と終了時の後処理など必須となる処理を自動で実行try/finallyみたいなもの、最初と最後に何かしてくれるclass a(object): def_enter_(self): print 'sss' return 'sss111' def_exit__(self, type, value, traceback): print 'ok' return Falsewith a() as s: print sssssss111okPythonのwith文の正体 (zenn.dev)
初期値をエラー値にし、業務判定エラーでステータスを設定したらreturnで抜けるdef exFunction(self): self.status_error = STATUS_ERROR try: if XX = AAA: self.status_error = STATUS_XX_ERROR retrun self.status_error = STATUS_SUCCESS retrun except: ~エラー処理、ステータスは変更しない
エラーメッセのハードコーディングを避ける方法(ハードが場所と内容が分かり易いかも)MSG_ERROR_OLD_EMAIL = "Error: 旧メール%sです\n"e_message_list.append(MSG_ERROR_OLD_EMAIL % (old_email))self.error_message = '\n'.join(e_message_list)

ケチって分厚い本1冊にしたが全然進まぬ、薄い奴星e、?チッPython、誰がJSONじゃ~い、チェーンソー魔わすっぞ
続編、、モジュールとかmportとか、
/// BANGBOO BLOG /// - Python Python
(More)
Comment (0)

■20/12/25 1:06AM
Promise
仕事は炎上芸なり~と勤しむ炎上芸人にも分かるように解説をさせて頂きたく候
(勤しむところはソコではない)

///promise/async/await 非同期関数
【ES6】 JavaScript初心者でもわかるPromise講座 - Qiitahttps://rightcode.co.jp/blog/information-technology/javascript-promisehttps://rightcode.co.jp/blog/information-technology/javascript-async-awaithttp://www.tohoho-web.com/ex/promise.htmlhttps://sbfl.net/blog/2016/07/13/simplifying-async-code-with-promise-and-async-await/https://qiita.com/niusounds/items/37c1f9b021b62194e077https://qiita.com/soarflat/items/1a9613e023200bbebcb3非同期関数は処理の順序を制御できない問題があった、そこでPromise↓Promise オブジェクトは then(ok_callback, ng_callback) というメソッドを持ちます。then() はPromise が成功または失敗になるまで処理を受け流し、処理を.then()で繋げ順番を確保することが可能成功時に ok_callback を、失敗時に ng_callback をコールバック関数として呼び出します.then() は第一引数に成功時のコールバック関数、第二引数に失敗時のコールバック関数.catch(ng_callback) は、.then(undefined, ng_callback) と同じ意味.catch() は処理中に発生した throw をキャッチできるES2018(ES9) では、.finally() がサポートされましたfunction aFunc3(data) {    return new Promise(function(okCallback, ngCallback) {        setTimeout(function() {            if (Math.random() < 0.30) {                ngCallback(new Error('ERROR!'));            } else {                okCallback(data * 2);            }        }, Math.random() * 1000);    });}function sample_finally2() {    aFunc3(100).then((data) => {        console.log(data);        return aFunc3(data);    })    .then((data) => {        console.log(data);        return aFunc3(data);    })    .then((data) => {        console.log(data);         throw new Error('ERROR!!!');    })    .catch((e) => {        console.log("catch");        console.log(e);    })    .finally(() => {        console.log('*** Finally ***');    });}//200 400 800 catch Error:ERRROR!!! *** Finally ***Promise.all() は配列で指定された全てのPromiseタスクを待ち全てが完了した時点で .then()を呼ぶPromise.race()ならいずれかのPromisefunction sample_all() {    p1 = taskA();    p2 = taskB();    Promise.all([p1, p2]).then(() => {        console.log("taskA and taskB are finished.");    });}↓ES2017 では、async/await がサポートされましたasync と await を用いることで、Promise に対応した非同期関数を、同期関数の様にシンプルに呼び出すことが可能となります同期関数の様に呼び出したい非同期関数を呼び出す際に await をつけます。await を呼び出す関数に async をつけますasync function sample_async_await_with_catch() {    var val = 100;    try {        val = await aFunc3(val);        console.log(val);        val = await aFunc3(val);        console.log(val);        val = await aFunc3(val);        console.log(val);    } catch (e) {        console.log(e);    }}
■コールバック関数広い定義でいうと「高階関数に渡すための関数」「関数を受け取る関数」は「高階関数」、つまりhello()がコールバック関数// 関数を2回実行する関数!!function doTwice(func) {  func(); // 1回目Hello!  func(); // 2回目Hello!}// あいさつするだけの関数function hello() {  console.log('Hello!');}// あいさつを2回実行するdoTwice(hello);
========================================
もっと詳しく、もっと分かり易く、どう使うか↓

https://knowledge.sakura.ad.jp/24890/https://jsprimer.net/basic/async/https://dev.classmethod.jp/articles/javascript-asynchronous-processing/■処理の繋がり1)コールバック関数 ある関数の処理が終われば次のコールバック関数を呼ぶという指定がそれ 歴史的にはエラーファーストコールバック(のルール)  処理が失敗した場合は、コールバック関数の1番目の引数にエラーオブジェクトを渡して呼び出す  処理が成功した場合は、コールバック関数の1番目の引数にはnullを渡し、2番目以降の引数に成功時の結果を渡して呼び出す  fs.readFile("./example.txt", (error, data) => {

2)Promise(非同期処理に対するPromise→順番を合わせる意味では同期処理ではと思う?JSはシングルスレッドかつ非同期という糞?仕様) ある関数の処理が終わればPromiseオブジェクトを返す JSがシングルスレッドだが 処理を一定の単位ごとに分け処理を切り替えながら実行する並行処理(concurrent)の仕様のため 順序を考慮する必要がある  非同期処理の実行中にとても重たい処理があると非同期処理の切り替えが遅れる
Promiseオブジェクトは3つの内部状態を持ちます。 pending(保留): まだ非同期処理は終わっていない(成功も失敗もしていない) fulfilled(成功): 非同期処理が正常に終了した rejected(拒否): 非同期処理が失敗した  初期状態はpendingで、一度fulfilledまたはrejectedになったらそれ以降は状態は変わらず、非同期処理の終了時に返す値もそれ以降は変わらない
Promiseのコンストラクターは関数を引数に取って、その関数がさらに2つの関数を引数に取る 1番目の関数(resolve)に引数を渡して実行すると状態がfulfilledになり、引数の値はPromiseオブジェクトが保持する値になる 2番目の関数(reject)に引数を渡して実行すると状態がrejectedになり、引数の値はPromiseオブジェクトが保持する値になる 関数が例外を投げた場合も状態がrejectedになり、投げた値がPromiseオブジェクトが保持する値になる、throwする値をrejectedに渡して実行した時と同じ
then()は2つの関数を引数に取り、Promiseの状態がfulfilledになったら1番目の関数が、rejectedになったら2番目の関数が実行されます。 then()の1番目の引数が関数でなければidentity function(入力値をそのまま返す関数)が代わりに使われます 2番目の引数が関数でなければthrower function(入力値を例外として投げる関数)が代わりに使われます  catch()は1番目の引数にidentity functionを指定したthen()と同じ
上の挙動をオレオレPromiseをYakusokuで作っているので分かり易い https://knowledge.sakura.ad.jp/24890/
なお、本質としてはコレ、下記ソースが決まりの流れ、ひな形としてヤリ慣れるしか1)時間が掛かる処理をPromise化して順序立てよう2)成功と失敗のコールバックを指定しよう
//処理にコールバック関数を入れて成功と失敗時の型で終えるfunction dummyFetch(cmt, callBack) {    setTimeout(() => {        if (cmt.startsWith("/success")) {            callBack(null, { body: `Response body of ${cmt}` });        } else {            callBack(new Error("Bad"));        }    }, 1000 * Math.random());}//プロミスを入れるためラッパーを関数にかますfunction aaaFilePromise(cmt) {  return new Promise((resolve, reject) => {    dummyFetch(cmt, (err, data) => {      if (err) {        reject(err); // 失敗: 内部状態をrejectedにする      }      else {        resolve(data); // 成功: 内部状態をfulfilledにする      }    });  });}//プロミスチェーンでのフローaaaFilePromise("/success/passwd")  .then((data) => { // 読み出しに成功したらresolve()に渡した値が引数として渡される    console.log("1", data);    //return 'next';//テキストがあってもなくても次のthenに行く、省略でもテキストでも第一引数関数に行く成功側    return aaaFilePromise("/etc/text");//エラーで次のthenの失敗側の第二引数関数にきっちり行く  })  .then((data) => {    console.log("2", data);    return aaaFilePromise("/success/shadow1");  }, (data) => {    console.log("2e", data);    return aaaFilePromise("/success/shadow2");  })  .then((data) => {    console.log("3", data);    return aaaFilePromise("/etc/shadow");  })  .catch((err) => { // reject()に渡した値が引数として渡される    console.log("error", err);  });
then()/ catch()は、引数で渡された関数の戻り値から新たにPromiseオブェクトを作り、そのオブジェクトを返します。そのためメソッドチェーンが可能  引数に渡した関数の戻り値がPromiseオブジェクトの場合はそのオブジェクトをそのまま返す、そうでなければ戻り値をPromiseで包んで返す エラーでキャッチに飛ぶ訳ではなく次のthen第2引数関数に飛んでいる、省略でcatchに行っているように見えるだけ
dexieやPWAでの提供があり使う(処理を順序立てて使うようプログラムを組む時にdexie: db.schedule.where('site').equals('sche').first().then(function(records) {pwa: caches.keys().then(function(keyList){return Promise.all(keyList.map(function(key){

3)async / await
promiseは順番決めができたがasync/awaitは順番を扱う処理もできる
setTimeout/setIntevalがプロミスチェーンだけでは時間を止められない
 シングルスレッドから似非スレッドで分離し非同期になるから、awaitを入れると同期する↓
const wait = (sec) => {  return new Promise((resolve, reject) => { setTimeout(resolve, sec*1000);  });};async function arrKick_async(arr) {    for(let i=1; i<=num_arr; i++){      arr = await kickPromise(arr);      await wait(2);
    }}arrKick_async(arr);

========================================JSネイティブとPromiseとasyncが混ざった場合は同期しない、then()すら超えてくる↓
4)コールバック地獄
結局コールバック地獄が扱いやすい(スレッドの切り替えがなければ同期ができる)、最近のJSフレームワークは全部Promise化しているらしいが
例)キャッシュを保存し、そのステータスを取るようにAsyncやPromiseで保存待ちの順番をにしても、待たない
//隙間がないと1度エラーだとエラーになりっぱなしlet num_cache;num_cache = getCacheStatus();if(num_cache == 0 || !num_cache){ num_cache = getCacheStatus(); if(num_cache == 0 || !num_cache){ num_cache = getCacheStatus(); if(num_cache == 0 || !num_cache){ num_cache = getCacheStatus(); if(num_cache == 0 || !num_cache){
//setTimeoutで隙間があっても関数スレッドの返り値を代入するスレッド切替時に、返り値を待つスレッドの方は次の処理に進んでしまいIF判定ができないlet s = setTimeout(function(){ let num_cache1 = getCacheStatus(); if(num_cache1 == 0 || !num_cache1){ s = setTimeout(function(){ let num_cache2 = getCacheStatus(); if(num_cache2 == 0 || !num_cache2){ s = setTimeout(function(){ let num_cache3 = getCacheStatus(); if(num_cache3 == 0 || !num_cache3){ s = setTimeout(function(){ let num_cache4 = getCacheStatus(); if(num_cache4 == 0 || !num_cache4){
//Func返り値やPromiseやAsyncでのスレッドの切り替えがないDOMの判定であれば上手くいくlet s = setTimeout(function(){ getCacheStatus(); if(document.getElementById('mes_filenames').innerHTML == 'none'){ s = setTimeout(function(){ getCacheStatus(); if(document.getElementById('mes_filenames').innerHTML == 'none'){ s = setTimeout(function(){ getCacheStatus(); if(document.getElementById('mes_filenames').innerHTML == 'none'){ s = setTimeout(function(){ getCacheStatus(); if(document.getElementById('mes_filenames').innerHTML == 'none'){ s = setTimeout(function(){ getCacheStatus(); if(document.getElementById('mes_filenames').innerHTML == '<?php echo $lang_page->install_none; ?>'){
function getCacheStatus(){ let num_caches = 0; let num_success = 0; caches.keys().then(function(keyList){   return Promise.all(keyList.map(function(key){ caches.open(key).then(function(cache) { cache.matchAll().then(function(response) { document.getElementById('mes_filenames').innerHTML = ''; let s; let o; for(const value of response){ s = value.status; o = value.ok; document.getElementById('mes_filenames').insertAdjacentHTML('afterbegin', value.url + '<br>'); if(s == '200' && o){ num_success++; } num_caches++; } if(num_caches > 0){ document.getElementById('mes_progress_rate').innerHTML = 'Progress: ' + num_success / num_caches * 100 + '%'; }else{ document.getElementById('mes_filenames').innerHTML = 'None'; } }); });   })); }); return num_caches;}===============
thenの入れ子だと親の部分だけ先に進んでしまう、入れ子ダメで親子を作れば親→子の一方方向で子で終わるトーナメント構造で(上がらない)
test1().then((result) => {
test2().then((result) => { //fuok });})then(function() これは入れ子

test1().then((result) => {
test2().then((result) => { //fuok
})then(function(){ //fuok2 }); これでトーナメント構造
})catch(function(e)

promiseチェーンでthen毎にに欲しい引数を出すが、複数であればそれらの引数をthenに渡せない、下記1は駄目
 1)thenで一つの引数になるようにロジックを組む(thenのトーナメント構造、一階層上で変数に入れる等) }).then(function(response){ return [response.json(), arr_del]; }).then(function(v) { json = v[0]; arr = v[1];
 2)callbackとresolveに配列を使うとOK、オブジェクトでもいいかも
function dummyFetch(cmt, callBack) { if(Array.isArray(cmt){ var p = cmt[0]; var s = cmt[1]; }else{ var p = cmt; var s = 1; } setTimeout(() => {         if (p.startsWith("/success")) { var r = [p, ++s];//これ不可[p, s++] callBack(null, r);         } else {             callBack(new Error("Bad"));         }     }, 1000 * Math.random()); } function aaaFilePromise(cmt) {   return new Promise((resolve, reject) => {     dummyFetch(cmt, (err, data) => {       if (err) {         reject(err);       }       else {         if(Array.isArray(data){ var p = data[0]; var s = data[1]; }else{ var p = data; var s = 1; } resolve([p, s]); // 成功: 内部状態をfulfilledにする       }     });   }); }===============
Promise化していない関数を使いたいが、そのまま使うかthen化できるようにするか? 1)次thenに進みたい元Funcの処理としてresolveの返り値に入れる、ダメなら省略可だがreject()に渡しcatchする
 2)次thenには適当でもいいのでreturnで進む function test1 () {   return new Promise((resolve, reject) => {     const a = 1;     const b = 2;     resolve([a, b]);   }) } test1().then((result) => {   console.log(result[0]); // 1   console.log(result[1]); // 2
  return 'go next'; }).then(function(){

エラーハンドリングしたい、よくわからんが下記で動作に違いがでた、rejectはJSがエラーを吐いた
 1)catchさせるにはthrow new Errorし、alertを出す
 2)catchはしないが次のthenには移動させないためreturn false
}).then(function(json){ if(json.init == 'Not appropriate access'){ throw new Error('Server warning'); }else if(json.init == 'No data'){ //reject("initiate!"); return false; }else{
resolve(json);
} }).catch(function(error){ alert('Ooops:  ' + error); });Promise.allを使って、3つのpromiseを同時に実行、allはすべての非同期処理がresolveされたタイミングで結果を返 Promise.all([test1, test2, test3]).then(function() {     console.log("Fourth");もっと簡単に async, await, Promise - Qiita

■Javascript
https://www.bangboo.com/cms/blog/page_325.html


Comment (0)

■20/4/21 12:00AM
Dexie
Indexeddbを使うならラッパーが要るやろ、とオモて、溺死やったらコレ便利やんってちゃうか、とオモて、知らんけど
■構造 DB > Table > kvs > record(db=)schedule_db > schedule(=table) > kvs(Key=自動採番:Value=json=record)
kvsはid++が先頭に来ずでこう→ 1:"{"name":"aaa",reg_date":"20201027_11:57:24","id":1}"

var db = new Dexie("schedule_db");db.version(1).stores({schedule: '++id,name,reg_date'});
■操作var db = new Dexie("schedule_db"); schedule_dbというDBがセットされschedule: '++id,name,key,reg_date' テーブルscheduleにカウントアップKey:JSON{id,name,key,reg_date}が入るもしschedule: 'name,key,reg_date'ならnameが自動で一番最初のカラムだからキーになるキーの値が同じだとAddができない
stores()で一番最初に来るのが「主キー」put()は追加しあれば更新、add()は追加のみで同キーがあればエラー
 put()はupdateとしてDB上上書きされるように見えるがループすると全データが出てくる、謎first()やlimit()やlast()で欲しいレコードを取得toArray()ではobjが返るがobjは配列で引数0をつけてアクセス obj[0]get('aaa')はkey=aaaの値を持つ最初の行、get({key: "sss", value: "ccc"})で条件付可delete()の返り値Promiseに削除件数が入っている
■削除のレベルは行、表、DB行削除 db.schedule.where({id: id}).delete().then (function(records){表削除 trancateで db.schedule.clear(); コンソールには反映されていないがレコード削除済 db.table(storeName) で操作あるいはtables ->だめだった 表を複数持てるdb.version(1).stores({    genres: '++id,name',    albums: '++id,name,year,*tracks',    bands: '++id,name,*albumIds,genreId'});db.delete() DBを消せる(その後新たに再作成できる)

■insertdb.schedule.add({name: "aaa", key: "bbb", reg_date: getCurrentTime()}).then (function(id){ return db.schedule.get(id);}).then(function (schedule) { alert ("Date was set at " + schedule.reg_date);
■select
db.reserve.each(function(records){
if(records == null || records == ''){ alert ("No data found"); }else{ records.json;
toArrayは複雑になる、eachの方がよいかも、toArrayとeachの入れ替えてのselect発行が基本できるみたい
db.reserve.where({flg_del: 2}).toArray(function(records){ records.forEach(function(record){//obj.forEach直で行ける Object.keys(record).forEach(function(key) {//直で行けずObject.keys().forEach()で let val = this[key]; if(key == 'json'){ let v = JSON.parse(val);//直で行けずパースが必要 Object.keys(v).forEach(function(k) { let v = this[k]; console.log(k, v); }, v); } }, record); });
複雑なものはOr句で出せる
db.reserve.where('reg_date').below(getCurrentTime()).or('flg_del').equals(2).limit(3).each(function(records){ console.log('List: ' + JSON.stringify(records));
And句はfunctionを取るが簡単な感じがする
db.reserve.where('datetime').below(display_expire_date).and(item => item.flg_del == 2).desc('datetime').limit(display_ex).each(function(records){

複数条件はwhereにオブジェクトとして記載するがbelow等のフィルターにつながらずエラー、シンプルならokだが
db.reserve.where({datetime, flg_del: 2}).below(display_expire_date).limit(display_ex).each(function(records){
複数条件にフィルターをつけるにはwhereに配列で記載するが一つはbelow、一つはequalsでフィルタが複数でうまくいかない、シンプルならokだが
db.reserve.where(["datetime", "flg_del"]).below([display_expire_date, 2]).limit(display_ex).each(function(records){

先頭行
db.schedule.where('name').equals('aaa').first().then (function(records){

x↓ダメ??db.schedule.where('name').equals('aaa').toArray(function(records){
alert(records.reg_date);
x↓ダメ??db.schedule.get({name: "aaa", key: "bbb"}).then (function(records){ alert (JSON.stringify(records)); for (let i in records) { alert(i + ' item has ' + records[i].reg_date); }
■Insert and select(キーのidを使う)db.schedule.add({name: "ver1.0", key: document.getElementById("inputKey").value, value: document.getElementById("inputValue").value, reg_date: getCurrentTime()}).then(function(){ db.schedule.get('2').then(function(records){ alert(JSON.stringify(records)); }).catch(function(error) { alert ("Ooops: " + error); });}).catch(function(error) { alert ("Ooops2: " + error);
■Update
putは存在があれば更新、なければ挿入
db.schedule.put({key: "bbb", reg_date: set_date}).then (function(){ return db.schedule.get('bbb');}).then(function (schedule) { alert ("Date was set at " + schedule.reg_date);
keyが出せる場合はupdate()db.friends.update(2, {name: "Number 2"}).then(function (updated) {

トランザクションや細かな変更はmodify()db.friends.where("shoeSize").aboveOrEqual(47).modify({isBigfoot: 1}); modify推奨?→ https://dexie.org/docs/Collection/Collection.modify()
■Deletedb.schedule.where({name: "aaa"}).delete().then (function(){ return db.schedule.toArray();}).then(function (records) { if(records == null || records == ''){ alert ("No data found"); }else{ alert (JSON.stringify(records)); }
■Where句
db.friends.where("shoeSize").between(40, 45).count(function(count) {
[HTML5] IndexedDBでデータの保存や読み込みを行う - Dexie.js編 (katsubemakito.net)
Dexie.jsとTypeScriptでIndexedDBを操作する - noxi雑記 (hateblo.jp)

■アクセスindexeddbは該当DBにどこからアクセスできるか>同一ドメイン、ディレクトリでじゃない保存場所C:\Users\<ユーザ>\AppData\Local\Google\Chrome\User Data\Default\IndexedDBC:\Users\<ユーザ>\AppData\Roaming\Mozilla\Firefox\Profiles\XXXXX.default\storage\default
■課題SWで外部JSを扱うにはSW内に importScripts('dexie.js'); で埋め込むSyntaxError: Unexpected token o in JSON at position 1 はオブジェクトが返っている
JSONはオブジェクトで扱うのが楽 JSON.stringify(records)とJSON.parse(records)で変換
console.log('json: ' + JSON.stringify(json)); for(i = 0; i < json.length; i++){ if(json[i] != null) { console.log('id: ' + json[i].id);
下のようなロジックはあるテーブルのSELECTループ中に他のテーブルにアクセスする入れ子なのでエラー「NotFoundError: Failed to execute 'objectStore' on 'IDBTransaction': The specified object store was not found.」→配列に入れてIndeDBの問い合わせを一旦完了し、配列のループでIndedbを操作self.addEventListener('sync', function(event){ db.que.each(function(records){ if(event.tag.startsWith('post-data:' + records.tag)){ event.waitUntil(postDataSW(db)); } }); function postDataSW(){ db.reserve.where({flg_server: 2}).toArray(function(records){DevTools failed to load SourceMap: Could not load content~のエラーが出た 効果あるか不明だがdexieの最終行のコレを削除した、文字コードがUTF8に変えたりも //# sourceMappingURL=include.prepload.js.map
■関連JS、JavascriptJSでAタグリンクを挿入するにはinsertAdjacentHTMLがよい生成したタグを追加する前に掃除するにはdocument.getElementById('xx').textContent = null;
■テストhttps://www.bangboo.com/indexeddb/indexeddb_dexie_form.htmlhttps://www.bangboo.com/indexeddb/test/indexeddb_dexie_form.html (ディレクトリ違い)
Comment (0)

Navi: <  10 | 11 | 12 | 13  >
-Home
-Column [133]
-Europe [9]
-Gadget [77]
-Web [137]
-Bike [4]

@/// BANGBOO BLOG ///