装纯掩盖桑

文章 评论 浏览 26

装纯掩盖桑 2025-02-10 15:04:51

更新此行:

mapView.userTrackingMode = .followWithHeading

Update this line:

mapView.userTrackingMode = .followWithHeading

如何显示在哪个侧用户转动电话,如果我使用MKMAPVIEW显示用户位置

装纯掩盖桑 2025-02-10 14:19:14

首先创建一个符合可解码的结构。映射JSON数据是一件好/必要的。

struct MyStruct: Decodable {
    let tn_newsid: Int
    let tn_midashi: String
    let tn_name: String
    let tn_ktel: String
    let tn_url: String
    let tn_kdo: Double
    let tn_ido: Double
    let tn_im1name: String
    let tn_im2name: String
    let tn_im3name: String
    let tn_im4name: String
    let type: Int
    let nico_recommended: Int

}

然后假设您的JSON响应看起来像这样:

let responseData: String = """
        [
        {
          "tn_newsid": 1477,
          "tn_midashi": "知床半島とオホーツク海の絶景が広がる",
          "tn_name": "北海道立オホーツク公園オートキャンプ場てんとらんど",
          "tn_ktel": "0152-45-27",
          "tn_url": "",
          "tn_kdo": 144.239526856306,
          "tn_ido": 43.9880220633556,
          "tn_im1name": "144377_1.jpg",
          "tn_im2name": "144377_2.jpg",
          "tn_im3name": "144377_3.jpg",
          "tn_im4name": "144377_4.jpg",
          "type": 0,
          "nico_recommended": 2
        },
        {
          "tn_newsid": 144377,
          "tn_midashi": "知ホーツク海の絶景が広がる",
          "tn_name": "北海道立オホートキャンプ場てんとらんど",
          "tn_ktel": "0152-45-27",
          "tn_url": "",
          "tn_kdo": 144.239526856306,
          "tn_ido": 46.9880220633556,
          "tn_im1name": "144377_1.jpg",
          "tn_im2name": "144377_2.jpg",
          "tn_im3name": "144377_3.jpg",
          "tn_im4name": "144377_4.jpg",
          "type": 0,
          "nico_recommended": 0
        }
            ]
            """

现在解析这样的响应:

let jsonData = responseData.data(using: .utf8)!
let decodedItems: [MyStruct] = try! JSONDecoder().decode([MyStruct].self, from: jsonData)
decodedItems.forEach({print(">>> \($0)")})

实际上,您最好避免使用强制解析数据和解码项目。

输出:

>>> MyStruct(tn_newsid: 1477, tn_midashi: "知床半島とオホーツク海の絶景が広がる", tn_name: "北海道立オホーツク公園オートキャンプ場てんとらんど", tn_ktel: "0152-45-27", tn_url: "", tn_kdo: 144.239526856306, tn_ido: 43.9880220633556, tn_im1name: "144377_1.jpg", tn_im2name: "144377_2.jpg", tn_im3name: "144377_3.jpg", tn_im4name: "144377_4.jpg", type: 0, nico_recommended: 2)
>>> MyStruct(tn_newsid: 144377, tn_midashi: "知ホーツク海の絶景が広がる", tn_name: "北海道立オホートキャンプ場てんとらんど", tn_ktel: "0152-45-27", tn_url: "", tn_kdo: 144.239526856306, tn_ido: 46.9880220633556, tn_im1name: "144377_1.jpg", tn_im2name: "144377_2.jpg", tn_im3name: "144377_3.jpg", tn_im4name: "144377_4.jpg", type: 0, nico_recommended: 0)

First create a struct that conforms to Decodable. It's good/necessary to map the JSON data.

struct MyStruct: Decodable {
    let tn_newsid: Int
    let tn_midashi: String
    let tn_name: String
    let tn_ktel: String
    let tn_url: String
    let tn_kdo: Double
    let tn_ido: Double
    let tn_im1name: String
    let tn_im2name: String
    let tn_im3name: String
    let tn_im4name: String
    let type: Int
    let nico_recommended: Int

}

Then let's say your JSON response looks like this:

let responseData: String = """
        [
        {
          "tn_newsid": 1477,
          "tn_midashi": "知床半島とオホーツク海の絶景が広がる",
          "tn_name": "北海道立オホーツク公園オートキャンプ場てんとらんど",
          "tn_ktel": "0152-45-27",
          "tn_url": "",
          "tn_kdo": 144.239526856306,
          "tn_ido": 43.9880220633556,
          "tn_im1name": "144377_1.jpg",
          "tn_im2name": "144377_2.jpg",
          "tn_im3name": "144377_3.jpg",
          "tn_im4name": "144377_4.jpg",
          "type": 0,
          "nico_recommended": 2
        },
        {
          "tn_newsid": 144377,
          "tn_midashi": "知ホーツク海の絶景が広がる",
          "tn_name": "北海道立オホートキャンプ場てんとらんど",
          "tn_ktel": "0152-45-27",
          "tn_url": "",
          "tn_kdo": 144.239526856306,
          "tn_ido": 46.9880220633556,
          "tn_im1name": "144377_1.jpg",
          "tn_im2name": "144377_2.jpg",
          "tn_im3name": "144377_3.jpg",
          "tn_im4name": "144377_4.jpg",
          "type": 0,
          "nico_recommended": 0
        }
            ]
            """

Now parse the response like this:

let jsonData = responseData.data(using: .utf8)!
let decodedItems: [MyStruct] = try! JSONDecoder().decode([MyStruct].self, from: jsonData)
decodedItems.forEach({print(">>> \($0)")})

In practice, you'd better avoid force-unwrapping data and decoded items.

Output:

>>> MyStruct(tn_newsid: 1477, tn_midashi: "知床半島とオホーツク海の絶景が広がる", tn_name: "北海道立オホーツク公園オートキャンプ場てんとらんど", tn_ktel: "0152-45-27", tn_url: "", tn_kdo: 144.239526856306, tn_ido: 43.9880220633556, tn_im1name: "144377_1.jpg", tn_im2name: "144377_2.jpg", tn_im3name: "144377_3.jpg", tn_im4name: "144377_4.jpg", type: 0, nico_recommended: 2)
>>> MyStruct(tn_newsid: 144377, tn_midashi: "知ホーツク海の絶景が広がる", tn_name: "北海道立オホートキャンプ場てんとらんど", tn_ktel: "0152-45-27", tn_url: "", tn_kdo: 144.239526856306, tn_ido: 46.9880220633556, tn_im1name: "144377_1.jpg", tn_im2name: "144377_2.jpg", tn_im3name: "144377_3.jpg", tn_im4name: "144377_4.jpg", type: 0, nico_recommended: 0)

获取JSON文件作为NSarray仅包含第一个字符

装纯掩盖桑 2025-02-10 05:29:47

意图getIntent()函数活动 class上的速记。您的视图模型无法访问它,而且它可能不应该处理意图 s。只需将您想要的数字传递到功能中:

fun loadAllQuestions(type: Int) {
    // treating type == 0 as the default
    val jsonStr = "${if (type == 1) "mcq2" else "mcq1"}.json".loadJSONFromAsset()
}

或者更好,为每种类型的一些有意义的名称枚举

enum class QuestionType(val filename: String) {
    COOL("mcq1.json"), HARD("mcq2.json")
}

,然后使用这些枚举,因此您不会处理魔术数字,并且更清楚的是,

fun loadAllQuestions(type: QuestionType) {
    // no need for a default, you can only pass in valid values now
    val jsonStr = type.filename.loadJSONFromAsset()
}

活动中发生了什么,您可以检查您的意图,解决哪个QuestionType您的号码与之相关,然后将其传递到loadAllQuestions调用中。您甚至可以直接使用枚举值,而不是int使用put/getSerializableExtra(如果愿意)!


我添加了一个默认结果,而不是使用null,如果数字不有效,但是如果您确实想要nulls,则可以执行此操作:

fun loadAllQuestions(type: Int) {
    val jsonStr = when(type) {
        0 -> "mcq1.json"
        1 -> "mcq2.json"
        else -> null
    }?.run { loadJSONFromAsset() } // only runs if the result isn't null
}

// nullable param now, in case there's no valid value in your extra
fun loadAllQuestions(type: QuestionType?) {
    // defaults to null if type is null
    val jsonStr = type?.filename?.loadJSONFromAsset()
}

intent is shorthand for the getIntent() function on the Activity class. Your view model can't access it, and it probably shouldn't be dealing with Intents anyway. Just pass the number you want into the function:

fun loadAllQuestions(type: Int) {
    // treating type == 0 as the default
    val jsonStr = "${if (type == 1) "mcq2" else "mcq1"}.json".loadJSONFromAsset()
}

or better, make an enum with some meaningful names for each type

enum class QuestionType(val filename: String) {
    COOL("mcq1.json"), HARD("mcq2.json")
}

and use those, so you're not dealing with magic numbers and it's clearer what's happening

fun loadAllQuestions(type: QuestionType) {
    // no need for a default, you can only pass in valid values now
    val jsonStr = type.filename.loadJSONFromAsset()
}

then in the activity, you can check your Intent, work out which QuestionType your number relates to, and pass it into the loadAllQuestions call. You can even use the enum value directly instead of an Int with put/getSerializableExtra if you like!


I added a default result instead of using null if the number isn't valid, but if you do want nulls, you can do this:

fun loadAllQuestions(type: Int) {
    val jsonStr = when(type) {
        0 -> "mcq1.json"
        1 -> "mcq2.json"
        else -> null
    }?.run { loadJSONFromAsset() } // only runs if the result isn't null
}

or

// nullable param now, in case there's no valid value in your extra
fun loadAllQuestions(type: QuestionType?) {
    // defaults to null if type is null
    val jsonStr = type?.filename?.loadJSONFromAsset()
}

在ViewModel Android中getintextra

装纯掩盖桑 2025-02-10 03:24:15

我个人可以推荐“ Roots Bud” - 它具有您需要的所有内容,只需要很少的调整即可。它专门为WordPress制作。

https://roots.io/bud/

另外,您也可以使用“根10”主题启动器,它已经包含了构建过程。但是,总体而言,它是非常先进的,因此建议对WordPress的工作方式有很好的了解。

I personally can recommend "Roots Bud" - it has everything you need included, and needs only little tweaking. It is made for Wordpress specifically.

https://roots.io/bud/

Alternatively you could also use "Roots Sage 10" theme starter, which already has the build process included. However it is quite advanced in general, so a good knowledge of how Wordpress works is recommended.

如何使用 @WordPress/脚本和NPM为WordPress网站设置JS的构建环境?

装纯掩盖桑 2025-02-09 23:08:22

想法是计算连续b,直到我们找到a。我遵循的步骤

  1. 跟踪我在找到“ a”之前找到了多少b
  2. 如果找到a,则将b计数添加到主 output 并重置下一次连续搜索的值。
  3. 如果找不到a,则只需丢弃b计数跟踪器即​​可。
//Removing the first and last unnecessary B
String s1 = "BBBAAAABBBBAABB";
s1= s1.substring(s1.indexOf("A"),s1.lastIndexOf("A"));

int output=0;
int bFound=0;
for (int i = 0; i < s1.length(); i++) {
  if(s1.charAt(i)=='B'){
    System.out.println("B Found");
    bFound++;
  }else if(bFound>0 && s1.charAt(i)=='A'){
    output+=bFound; //adding to main output plus resetting the count  
    bFound=0;
  }
}

System.out.println("Total B to remove: "+output);
if(output>0){
  // your print statement
}else{
  // your print statement
}

Idea is to count consecutive B until we find an A. Steps I have followed

  1. Keep track of how many B I have found till I find an 'A'.
  2. If A found then add the B Count to the main output and reset the value for the next consecutive searching.
  3. If A not found then simply discard the B Count tracker.
//Removing the first and last unnecessary B
String s1 = "BBBAAAABBBBAABB";
s1= s1.substring(s1.indexOf("A"),s1.lastIndexOf("A"));

int output=0;
int bFound=0;
for (int i = 0; i < s1.length(); i++) {
  if(s1.charAt(i)=='B'){
    System.out.println("B Found");
    bFound++;
  }else if(bFound>0 && s1.charAt(i)=='A'){
    output+=bFound; //adding to main output plus resetting the count  
    bFound=0;
  }
}

System.out.println("Total B to remove: "+output);
if(output>0){
  // your print statement
}else{
  // your print statement
}

计算&#x27; b&#x27;在字符串中,所有a&#x27; s在一起

装纯掩盖桑 2025-02-09 01:57:16

主函数上的数组仍然为空。更好的方法是在初始化之后调用print_array()函数。您只需将print_array(arrr)放入init_array()之后,然后在for loop语句之后。

the array on your main function is still NULL. the better way to do is just call the print_array() function after you initialize it. you just simply put print_array(arrr) inside init_array() and after the for loop statement.

动态数组int打印问题 - 也许不是有效的内存单元格

装纯掩盖桑 2025-02-09 00:01:14

简短答案:否。Github

主持包含代码的GIT存储库,但不运行代码。 GitHub页面可以提供静态站点,但无法运行服务器端代码,其中包括Node.js和Express。如果您想免费托管这样的东西,建议您查看 heroku

Short answer: No.

GitHub hosts git repositories containing code, but doesn't run code. GitHub pages can serve static sites, but cannot run server side code, which include node.js and express. If you want to host something like this for free, I suggest looking into Heroku.

有没有办法在github上托管socket.js服务器?

装纯掩盖桑 2025-02-08 20:24:19

同时定义两个商店似乎有些不必要,具体取决于预期的语义。它也可以通过一个来源和一个派生的商店来接近。

<script>
    import { transformed } from './transform-store.js';
    import { writable } from 'svelte/store';

    const number = writable(13);
    const json = transformed(number, {
        in: value => JSON.stringify({ x: value }),
        out: value => { try { return JSON.parse(value).x; } catch(err) { return NaN; } },
    });
</script>

Number to JSON:
<input bind:value={$number} type="number" />
<input bind:value={$json} />

transform-store.js

import { derived } from 'svelte/store';

export function transformed(store, options) {
    const identity = x => x;
    const transformIn = options.in ?? identity;
    const transformOut = options.out ?? identity;
    
    const { subscribe } = derived(store, $store => transformIn($store));
    const set = value => store.set(transformOut(value));
    
    return { subscribe, set };
}

3.48.0从本质上讲,它是通过定义修改源存储的自己的set函数来增强的衍生商店。


这也可以通过使用反应性陈述和属性描述符:

<script>
    function transformed(get, set) {
        const o = {};
        Object.defineProperty(o, 'value', { get, set });
        
        return o;
    }

    let number = 13;
    $: json = transformed(
        () => JSON.stringify({ x: number }),
        value => { try { number = JSON.parse(value).x; } catch(err) { number = NaN; } },    
    )
</script>

Number to JSON:
<input bind:value={number} type="number" />
<input bind:value={json.value} />

不过,理想情况下,只会对此提供内置的语言支持。

Defining two stores at the same time seems a bit unnecessary, depending on intended semantics. It could also be approached as there being one source and a derived store.

<script>
    import { transformed } from './transform-store.js';
    import { writable } from 'svelte/store';

    const number = writable(13);
    const json = transformed(number, {
        in: value => JSON.stringify({ x: value }),
        out: value => { try { return JSON.parse(value).x; } catch(err) { return NaN; } },
    });
</script>

Number to JSON:
<input bind:value={$number} type="number" />
<input bind:value={$json} />

transform-store.js

import { derived } from 'svelte/store';

export function transformed(store, options) {
    const identity = x => x;
    const transformIn = options.in ?? identity;
    const transformOut = options.out ?? identity;
    
    const { subscribe } = derived(store, $store => transformIn($store));
    const set = value => store.set(transformOut(value));
    
    return { subscribe, set };
}

REPL

The transformed store is essentially a derived store augmented to be writable by defining its own set function that modifies the source store.


This can also be done without stores by using reactive statements and property descriptors:

<script>
    function transformed(get, set) {
        const o = {};
        Object.defineProperty(o, 'value', { get, set });
        
        return o;
    }

    let number = 13;
    $: json = transformed(
        () => JSON.stringify({ x: number }),
        value => { try { number = JSON.parse(value).x; } catch(err) { number = NaN; } },    
    )
</script>

Number to JSON:
<input bind:value={number} type="number" />
<input bind:value={json.value} />

REPL

Ideally there would just be built-in language support for this, though.

Svelte中的惯用方式与中间转换进行两种方式绑定

装纯掩盖桑 2025-02-08 10:01:26

为了避免问题,请在nextline(); 之后使用 nextint(); 之后,因为它有助于清除缓冲区。当您按输入 nextInt();不会捕获新行,因此请稍后跳过scanner代码。

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer

In order to avoid the issue, use nextLine(); immediately after nextInt(); as it helps in clearing out the buffer. When you press ENTER the nextInt(); does not capture the new line and hence, skips the Scanner code later.

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer

使用Next()或NextFoo()之后,Scanner跳过NextLine()?

装纯掩盖桑 2025-02-07 12:33:21

,因为主动设置为false。

登录页面将首先显示“

const HomePage = () => {
    const[active,setActive]=useState(false);
    return (
        <div>
            <Navbar activesetter={setActive} />
            <Login activestatus={active} />
            <div id="content">
            </div>
        </div>
    );
}

不活动”

const Login = (props) => {

    return(
    <div>
        <div>
        {props.activestatus ? "it is active" : "it is not active" }
        </div>
    </div>

    );

}

const Navbar = (props) => {
    const handleSubmit=(e)=> {
            e.preventDefault();
            props.activesetter(true);
        
    }
    return(
    <div>
        <form  onSubmit={handleSubmit}>
        <button  type="submit">Login</button>

        </form>
    </div>

    );

}

Login page will show "it is not active" first because active is set to false.but once you click on submit button it will show "it is active"

HomePage

const HomePage = () => {
    const[active,setActive]=useState(false);
    return (
        <div>
            <Navbar activesetter={setActive} />
            <Login activestatus={active} />
            <div id="content">
            </div>
        </div>
    );
}

Login

const Login = (props) => {

    return(
    <div>
        <div>
        {props.activestatus ? "it is active" : "it is not active" }
        </div>
    </div>

    );

}

Navbar

const Navbar = (props) => {
    const handleSubmit=(e)=> {
            e.preventDefault();
            props.activesetter(true);
        
    }
    return(
    <div>
        <form  onSubmit={handleSubmit}>
        <button  type="submit">Login</button>

        </form>
    </div>

    );

}

React按钮点击应更改DIV的显示值

装纯掩盖桑 2025-02-07 11:17:28

有多个选项可用,因为您没有提及框架版本,因此提到最通用的&amp;宽松的方式来做到这一点。

    $name = $request->name;

    if(!$validation->fails()) {
        $product = Product::find($id);
        $product->setSlugAttribute($request->name);
        

        if($product->save()) {
            return response()->json(200);
        }
    }else{
        return response()->json(['errors' => $validation->errors()],401);
    }

还有其他一些,您可以根据Laravel版本尝试。检查文档在这里

There are multiple option available, since you didn't mention your framework version so mentioning the most generic & easist way to do that.

    $name = $request->name;

    if(!$validation->fails()) {
        $product = Product::find($id);
        $product->setSlugAttribute($request->name);
        

        if($product->save()) {
            return response()->json(200);
        }
    }else{
        return response()->json(['errors' => $validation->errors()],401);
    }

There are a few others, you can try according to the Laravel version. Check the documentation here

更新时的slug被姓名替换

装纯掩盖桑 2025-02-07 07:25:16

在打字稿中分组的对象数组与此:

groupBy (list: any[], key: string): Map<string, Array<any>> {
    let map = new Map();
    list.map(val=> {
        if(!map.has(val[key])){
            map.set(val[key],list.filter(data => data[key] == val[key]));
        }
    });
    return map;
});

Grouped Array of Object in typescript with this:

groupBy (list: any[], key: string): Map<string, Array<any>> {
    let map = new Map();
    list.map(val=> {
        if(!map.has(val[key])){
            map.set(val[key],list.filter(data => data[key] == val[key]));
        }
    });
    return map;
});

如何按钥匙对对象进行分组?

装纯掩盖桑 2025-02-06 20:55:22

帮助我的解决方案正在使用.wheregreaterthanorequalto(“日期”,“ 01/5/2022”)。wherelessthanorequalto(“ date”,“ 31/5/2022”)。

solution which helped me is using .whereGreaterThanOrEqualTo("date", "01/5/2022").whereLessThanOrEqualTo("date", "31/5/2022").

如何根据日期范围从Firestore检索数据?

装纯掩盖桑 2025-02-06 13:42:14

装饰器处理同步和异步函数

您可以创建一个装饰函数,该功能可以处理同步和异步功能。

在下面的摘要中,logger是一种装饰函数,它具有作为参数的功能,并返回处理日志记录的装饰函数。

如果输入函数返回Promise,则使用 “ rel =“ nofollow noreferrer”> Promise.prototype.finally

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret.finally(() => console.log(`Ended: ${func.name}`));
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Ended: ${func.name}`);
      throw err;
    }
  };

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncAdd = logger(async function asyncAdd(a, b) {
  await sleep(1000).then();
  console.log(`Adding ${a} and ${b}`);
  return a + b;
});

const syncSubtraction = logger(function syncSubtraction(a, b) {
  console.log(`Subtracting ${b} from ${a}`);
  return a - b;
});

console.log(`Result of syncSubtraction(2, 1): ${syncSubtraction(2, 1)}`);
console.log("=========================");
asyncAdd(1, 2).then((res) => console.log(`Result of asyncAdd(1, 2): ${res}`));
.as-console-wrapper { max-height: 100% !important; top: 0; }

注意:

  1. 使用最后方法确保即使装饰了异步功能的“ ended” log即使失败了。

  2. 尝试...捕获块可确保同一件事,但对于同步函数。

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret.finally(() => console.log(`Ended: ${func.name}`));
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Ended: ${func.name}`);
      throw err;
    }
  };


const syncFail = logger(function syncFail() {
  console.log("Inside syncFail");
  throw new Error("Error in syncFail");
});

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncFail = logger(async function asyncFail() {
  await sleep(1000);
  console.log("Inside asyncFail");
  throw new Error("Error in asyncFail");
});

try {
  syncFail();
} catch (err) {
  console.log(err.message);
}
console.log("==========================");
asyncFail().catch((err) => console.log(err.message));
.as-console-wrapper { max-height: 100% !important; top: 0; }

处理错误案例的方式不同:

如果要处理错误方案的处理方式与成功方案不同,例如,通过打印错误日志而不是结束日志,请参阅下面的摘要:

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret
          .then((res) => {
            console.log(`Ended: ${func.name}`);
            return res;
          })
          .catch((err) => {
            console.log(`Errored: ${func.name}`);
            throw err;
          });
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Errored: ${func.name}`);
      throw err;
    }
  };

const syncFail = logger(function syncFail() {
  console.log("Inside syncFail");
  throw new Error("Error in syncFail");
});

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncFail = logger(async function asyncFail() {
  await sleep(1000);
  console.log("Inside asyncFail");
  throw new Error("Error in asyncFail");
});

try {
  syncFail();
} catch (err) {
  console.log(err.message);
}
console.log("==========================");
asyncFail().catch((err) => console.log(err.message));
.as-console-wrapper { max-height: 100% !important; top: 0; }

成功情景的行为没有改变:

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret
          .then((res) => {
            console.log(`Ended: ${func.name}`);
            return res;
          })
          .catch((err) => {
            console.log(`Errored: ${func.name}`);
            throw err;
          });
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Errored: ${func.name}`);
      throw err;
    }
  };

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncAdd = logger(async function asyncAdd(a, b) {
  await sleep(1000).then();
  console.log(`Adding ${a} and ${b}`);
  return a + b;
});

const syncSubtraction = logger(function syncSubtraction(a, b) {
  console.log(`Subtracting ${b} from ${a}`);
  return a - b;
});

console.log(`Result of syncSubtraction(2, 1): ${syncSubtraction(2, 1)}`);
console.log("=========================");
asyncAdd(1, 2).then((res) => console.log(`Result of asyncAdd(1, 2): ${res}`));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Decorator handling both synchronous and asynchronous functions

You can create a decorator function that handles both synchronous and asynchronous functions.

In the snippet below, logger is a decorator function that takes in a function as it's argument and returns a decorated function that handles the logging.

If the input function returns a Promise, it's handled using Promise.prototype.finally.

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret.finally(() => console.log(`Ended: ${func.name}`));
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Ended: ${func.name}`);
      throw err;
    }
  };

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncAdd = logger(async function asyncAdd(a, b) {
  await sleep(1000).then();
  console.log(`Adding ${a} and ${b}`);
  return a + b;
});

const syncSubtraction = logger(function syncSubtraction(a, b) {
  console.log(`Subtracting ${b} from ${a}`);
  return a - b;
});

console.log(`Result of syncSubtraction(2, 1): ${syncSubtraction(2, 1)}`);
console.log("=========================");
asyncAdd(1, 2).then((res) => console.log(`Result of asyncAdd(1, 2): ${res}`));
.as-console-wrapper { max-height: 100% !important; top: 0; }

NOTE:

  1. Using the finally method ensures that the "Ended" log is printed even if the async function being decorated fails.

  2. The try...catch block ensures the same thing but for synchronous functions.

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret.finally(() => console.log(`Ended: ${func.name}`));
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Ended: ${func.name}`);
      throw err;
    }
  };


const syncFail = logger(function syncFail() {
  console.log("Inside syncFail");
  throw new Error("Error in syncFail");
});

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncFail = logger(async function asyncFail() {
  await sleep(1000);
  console.log("Inside asyncFail");
  throw new Error("Error in asyncFail");
});

try {
  syncFail();
} catch (err) {
  console.log(err.message);
}
console.log("==========================");
asyncFail().catch((err) => console.log(err.message));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Handling error cases differently:

If you want to handle the error scenario differently than the success one, for example by printing an error log instead of the end log, then refer to the snippet below:

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret
          .then((res) => {
            console.log(`Ended: ${func.name}`);
            return res;
          })
          .catch((err) => {
            console.log(`Errored: ${func.name}`);
            throw err;
          });
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Errored: ${func.name}`);
      throw err;
    }
  };

const syncFail = logger(function syncFail() {
  console.log("Inside syncFail");
  throw new Error("Error in syncFail");
});

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncFail = logger(async function asyncFail() {
  await sleep(1000);
  console.log("Inside asyncFail");
  throw new Error("Error in asyncFail");
});

try {
  syncFail();
} catch (err) {
  console.log(err.message);
}
console.log("==========================");
asyncFail().catch((err) => console.log(err.message));
.as-console-wrapper { max-height: 100% !important; top: 0; }

There's no change in the behavior of the success scenarios:

const logger =
  (func) =>
  (...args) => {
    console.log(`Started: ${func.name}`);
    try {
      const ret = func(...args);
      if (ret instanceof Promise) {
        return ret
          .then((res) => {
            console.log(`Ended: ${func.name}`);
            return res;
          })
          .catch((err) => {
            console.log(`Errored: ${func.name}`);
            throw err;
          });
      }
      console.log(`Ended: ${func.name}`);
      return ret;
    } catch (err) {
      console.log(`Errored: ${func.name}`);
      throw err;
    }
  };

const sleep = (timer) => new Promise((res) => setTimeout(res, timer));

const asyncAdd = logger(async function asyncAdd(a, b) {
  await sleep(1000).then();
  console.log(`Adding ${a} and ${b}`);
  return a + b;
});

const syncSubtraction = logger(function syncSubtraction(a, b) {
  console.log(`Subtracting ${b} from ${a}`);
  return a - b;
});

console.log(`Result of syncSubtraction(2, 1): ${syncSubtraction(2, 1)}`);
console.log("=========================");
asyncAdd(1, 2).then((res) => console.log(`Result of asyncAdd(1, 2): ${res}`));
.as-console-wrapper { max-height: 100% !important; top: 0; }

如何以允许在调用此功能之前和返回此功能后进行额外记录的方式包装 /装饰 /修改功能?

装纯掩盖桑 2025-02-06 07:16:39

看起来您没有设置PHP服务器。

首先,您需要http://localhost/index.php工作。当您的PHP代码工作时,请尝试发布Python的消息。

您可以在此处找到有关在服务器端设置PHP的信息: https://wwww.php。 NET/MANUAL/install.php

Looks like you didn't set up PHP server.

First of all, you need your http://localhost/index.php to work. When your PHP code will work then try to post message from Python.

You can find info about setting up PHP on the server side here: https://www.php.net/manual/install.php

如何从python传递变量并在PHP中接收它

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文