当前位置:网站首页 > C++编程 > 正文

completablefuture异步编程_pycharm好用的插件

工具: PlayGround


简介


ECMAScript 6 引入了异步操作的特性,主要特性有:

  • Promise 属于对象, 代表一个可能在未来完成的对象操作相关
  • Generator 属于函数, 可以通过 迭代器yield 来暂停函数的执行
  • async/await 属于操作符, 用于修饰 PromiseGenerator

注:async/await 的引入不是ES6,而是ES8

下面将详细的说明下。


Promise对象


先看下它的声明:

interface Promise<T> { 
    /* @func: 用于完成回调相关 @param onfulfilled 成功回调,它接受Promise的结果作为参数 @param onrejected 失败回调,它接受Promise的错误作为参数 @return 返回一个新的Promise对象 */ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>; /* @func: 对与then函数失败状态的补充,用于捕获Promise中的错误 @param: 失败回调 @return 返回一个新的Promise对象 */ catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>; } 

简单的理解就是: 使用Promise创建异步对象执行,要么成功,要么失败。

// 创建对象,参数: resolve表示成功时的回调函数, reject表示失败时的回调函数 const obj = new Promise(function(resolve, reject) { 
    resolve("sucess"); reject("failed"); }) // 使用then执行成功回调 obj.then((value:any) => { 
    console.log(value); // sucess }) // 使用catch执行失败回调 obj.catch((value:any) => { 
    console.log(value); }) 

注意:

  • 对象创建后就会执行,无法停止,直到成功或失败。
  • 要设置 resolvereject 的回调方法,否则对象内部会抛出错误,且不会显示到外部

then和catch

他们是 Promise对象的主要方法,特点有:

  1. 可以放在一起使用
const obj = new Promise((resolve, reject) => { 
    resolve("sucess"); reject("failed") }); // 要么执行成功回调,要么执行失败回调 obj.then((result) => { 
    console.log("Promise resolved:", result); }) .catch((error) => { 
    console.error("Promise rejected:", error); }); 
  1. 可以将多个then方法链接在一起,他们会按照顺序并独立运行
const obj = new Promise((resolve, reject) => { 
    resolve(1); }).then((value) => { 
    console.log("执行第1次回调", value); return value + 1; }).then((value) => { 
    console.log("执行第2次回调", value); }).then((value) => { 
    console.log("执行第3次回调", value); return Promise.resolve("resolve"); }).then((value) => { 
    console.log("执行第4次回调", value); return Promise.reject("reject"); }).then((value) => { 
    console.log("resolve:" + value); }, (error) => { 
    console.log("reject:" + error); }); /* // 创建时赋值1,将value+1的结果返回,并生成新的对象 "执行第1次回调", 1 // 新对象使用上个结果的参数2,无返回,并生成新的对象 "执行第2次回调", 2 // 新对象调用,上个参数因无返回则默认undefined, 生成新的对象并调用方法,赋值resolve "执行第3次回调", undefined // 获取到回调参数结果... "执行第4次回调", "resolve" "reject:reject" */ 

这个代码可以拆开理解为:

const obj = new Promise((resolve, reject) => { 
    resolve(1); }) const obj_1 = obj.then((value) => { 
    console.log("执行第1次回调", value); return value + 1; }) const obj_2 = obj_1.then((value) => { 
    console.log("执行第2次回调", value); }) const obj_3 = obj_2.then((value) => { 
    console.log("执行第3次回调", value); return Promise.resolve("resolve"); }) const obj_4 = obj_3.then((value) => { 
    console.log("执行第4次回调", value); return Promise.reject("reject"); }) const obj_5 = obj_4.then((value) => { 
    console.log("resolve:" + value); }, (error) => { 
    console.log("reject:" + error); }) /* "执行第1次回调", 1 "执行第2次回调", 2 "执行第3次回调", undefined "执行第4次回调", "resolve" "reject:reject" */ 

注: 每次的独立运行都会生成一个新的Promise对象,且接受上一个对象的结果作为参数

  1. 可以将多个catch方法链接在一起使用,使得错误依次进行。
const promise = new Promise((resolve, reject) => { 
    // 模拟异步操作 setTimeout(() => { 
    const randomNumber = Math.random(); if (randomNumber < 0.5) { 
    resolve("Operation completed successfully"); } else { 
    reject("Operation failed"); } }, 2000); }); promise .then((result) => { 
    console.log("Promise resolved:", result); }) .catch((error) => { 
    console.error("First catch:", error); throw new Error("Custom error"); }) .catch((error) => { 
    console.error("Second catch:", error.message); }); // "First catch:", "Operation failed"  // "Second catch:", "Custom error"  

Generator函数


主要通过yield将执行流程挂起, 通过next()方法执行下一步。 同普通函数区分主要有:

  • 函数是否存在yield表达式相关
  • 定义一定要使用function*

在创建Generator函数后,它并不会立即执行,而是返回一个迭代器对象;该对象可以通过next()方法逐步执行函数内部的代码。

function* loopFunc() { 
    for (let i = 0; i < 2; ++i) { 
    console.log("value:", i); yield i; } } const func = loopFunc(); const data1 = func.next(); // "value:", 0 console.log(data1); // {"value": 0,"done": false}  const data2 = func.next(); // "value:", 1  console.log(data2); // {"value": 1,"done": false} // 注意此处,函数已经执行完毕 const data3 = func.next(); console.log(data3); // {"value": undefined,"done": true}  

通过next()方法会返回两个对象:

  • value 表示函数yield表达式产生的值
  • done 表示函数是否执行完毕, true表示执行完毕,false表示函数还可以继续执行。

next函数

next()方法一般情况下是不会传入参数的,但支持参数传入,它的定义:

Generator<number, void, unknown>.next(...args: [] | [unknown]): IteratorResult<number, void> 

如果传入参数会作为上一个yield语句的返回值。

function* myGenerator() { 
    let result = yield; yield result + 10; } const gen = myGenerator(); // 第一次没有返回值, 故此value默认为undefined console.log(gen.next()); // { value: undefined, done: false } // 第二次参数5作为上一个yield的返回值,故此value为15 console.log(gen.next(5)); // { value: 15, done: false } 

因为Generator函数返回的是迭代器对象,所以同样可以使用for ...of进行循环遍历

function* myGenerator() { 
    yield 1; yield 2; yield 3; } let result: string = "" for (const value of myGenerator()) { 
    result += value; } console.log(result); // "123"  

return函数

Generator函数可以使用next()方法获取下一步的执行结果, 也可以使用return()来结束函数的执行。

function* demo() { 
    yield 1; yield 2; yield 3; } // 实例1: const myGen1 = demo(); console.log(myGen1.next()); // {"value": 1,"done": false} console.log(myGen1.next()); // {"value": 2,"done": false} console.log(myGen1.next()); // {"value": 3,"done": false} // 实例2: const myGen = demo(); console.log(myGen.next()); // {"value": 1,"done": false} console.log(myGen.return()); // {"value": undefined,"done": true} console.log(myGen.next()); // {"value": undefined,"done": true} 

两个例子进行对比,会发现return()方法强制终止了函数的执行。


yield* 表达式

它可用于在Generator函数中委托另一个Generator函数或可迭代对象的过程。

function* generator1() { 
    yield "a"; yield "b"; } function* generator2() { 
    yield* generator1(); yield "c"; yield "d"; } const gen = generator2(); console.log(gen.next()); // { value: 'a', done: false } console.log(gen.next()); // { value: 'b', done: false } console.log(gen.next()); // { value: 'c', done: false } console.log(gen.next()); // { value: 'd', done: false } console.log(gen.next()); // { value: undefined, done: true } 

至此,大概的用法介绍完毕,Generator函数了解到这几点大概够用了。



async和await 操作符


这两个关键字是从ES2017(ES8)版本引入的,与Promise对象和Generator函数有很大的关联,故此放到了一起来说明。

  • await 只能在异步函数内部使用,可用于等待一个Promise对象
  • async 用于声明函数是异步的, 函数内部可使用await来暂停函数的执行。

简单的实例:

// 实例1 async function demo1() { 
    console.log(1); console.log(2); } demo1(); console.log(3); // 1,2,3 // 实例2 async function demo2() { 
    await 1; console.log(1); console.log(2); } demo2(); console.log(3); // 3,1,2 

关于async, await和Promise对象的实例:

function delay(ms: number): Promise<string> { 
    return new Promise((resolve) => { 
    setTimeout(() => { 
    resolve("Delayed message"); }, ms); }); } async function asyncFunction() { 
    console.log("Before await"); const result = await delay(2000); console.log(result); console.log("After await"); } asyncFunction(); // "Before await" 先输出 // "Delayed message" 等待两秒钟后输出 // "After await"  

至此异步操作相关结束。


注意事项


异步编程在实际的应用开发中需要注意:

  1. 推荐使用async/await进行处理,使得代码易读和容易维护
  2. 使用try/catch捕获和处理异步操作中的异常
  3. 避免多层回调嵌套
  4. 注意异步操作的吮吸,避免处理逻辑问题

使用try/catch捕获异常的的简单示例:

function run(): Promise<void> { 
    return new Promise((resolve, reject) => { 
    setTimeout(() => { 
    const success = true; // 模拟异步操作成功或失败的情况 if (success) { 
    resolve(); } else { 
    reject(new Error("Failed to fetch data")); } }, 1000); }); } async function startRun() { 
    try { 
    await run(); console.log("run successfully"); } catch (error) { 
    console.error(error && error.message); } } startRun(); 
到此这篇completablefuture异步编程_pycharm好用的插件的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • ubuntuvscode配置c++环境_python环境搭建2024-11-18 13:54:10
  • vscode运行php配置_php编程软件2024-11-18 13:54:10
  • Harmony Native C++ 开发简单计算器2024-11-18 13:54:10
  • Mac C++编译安装OpenCV2024-11-18 13:54:10
  • c++编程自学_c++编程用什么软件2024-11-18 13:54:10
  • 异步编程 js_编程scratch32024-11-18 13:54:10
  • jacobi迭代法迭代次数_迭代法的基本原理2024-11-18 13:54:10
  • cam编程步骤_CAM软件编程2024-11-18 13:54:10
  • cam-tool编程教程_cam编程的基本流程2024-11-18 13:54:10
  • cam编程步骤_mastercam编程案例2024-11-18 13:54:10
  • 全屏图片