精华内容
下载资源
问答
  • 异步操作

    千次阅读 2012-03-03 14:57:45
    例子:在某个软件中,点击某个按钮会向服务器发送请求,这时在网络传输中可能产生很多事件阻碍,所以就要把该操作放在另一个线程中,即异步操作。 代码:需要写一个类继承AsyncTask,再覆写Void

    当一个线程执行的时候,可能会产生一些阻碍,这时用户就不能再执行当前线程的其他操作,可能需要等待其响应。于是,解决的办法就是把可能产生阻碍的步骤放在另一个线程上执行,这样当前线程的操作就可以不受影响。

    例子:在某个软件中,点击某个按钮会向服务器发送请求,这时在网络传输中可能产生很多事件阻碍,所以就要把该操作放在另一个线程中,即异步操作。

    代码:需要写一个类继承AsyncTask<Void,Void,Void>,再覆写Void doInBackground方法,在该函数中写要执行的可能产生阻碍的操作。执行该线程在主线程中使用该类的一个对象的excute方法。

    onPreExecute  该方法运行在UI线程中,可以对一些UI控件进行操作

    doInBackground  该方法并不运行在UI线程中,所以不能对UI控件进行修改

    在该方法内可以调用publishProgress(i)发布一些更新到UI线程。

    onProgressUpdate (i)该方法在UI线程中,可实现更新(如修改进度条),publishProgress的参数就是传到这里。

    onPostExecute  该方法在doInBackground  运行之后运行

    AsyncTask<A,B,C>

    C  doInBackground (A...Param)   A是参数类型,...的意思是可以传入多个A类型的数,Param是一个数组,保存参数。C是返回值类型

    onProgressUpdate(B)

    展开全文
  • 异步方法中取消异步操作

    千次阅读 2018-12-24 14:29:30
    1、在异步方法中取消异步操作,第一步必须声明CancellationToken和CancellationTokenSource两个类对象,并将两个类通过 CancellationTokenSource 对象的token属性关联; CancellationTokenSource cts = new ...

    1、在异步方法中取消异步操作,第一步必须声明CancellationToken和CancellationTokenSource两个类对象,并将两个类通过 CancellationTokenSource 对象的token属性关联;

    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken token = cts.Token; //将CancellationTokenSource cts对象与CancellationToken token对象关联

    2 、通过调用CancellationTokenSource的Cancel()方法使异步方法中或异步方法中的await表达式中的CancellationToken的IsCancellationRequested属性为True,从而终止异步方法或异步方法中的await表达式的执行。

     public async Task RunAsync(CancellationToken ct)//异步方法中多了CancellationToken类类型的形参
            {
                if(ct.IsCancellationRequested)
                {
                    return;
                }
                await Task.Run(() => CycleMethod(ct), ct);//public static Task Run(Action action, CancellationToken cancellationToken); Action是一个无参数无返回值的委托,为什么CycleMethod方法明明是一个有参数的委托
            }                                             //确能够在Run中使用

    3、异步方法或异步方法中的await表达式都包含一个CancellationToken类型的形参,只要程序调用CancellationTokenSource类的Cancel()方法,异步方法和await表达式中的方法检测到CancellationToken的IsCancellationRequested属性为True都会终止。

    程序一:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace _CancellationToken
    {
        class Program
        {
            static void Main(string[] args)
            {
                CancellationTokenSource cts = new CancellationTokenSource();
                CancellationToken token = cts.Token;        //将CancellationTokenSource cts对象与CancellationToken token对象关联
                MyClass mc = new MyClass();
                Task t = mc.RunAsync(token);
                Thread.Sleep(3000);//等待3秒
                cts.Cancel();
                t.Wait();
                Console.WriteLine("Was Cancelled: {0}",token.IsCancellationRequested);
                Console.ReadKey();
            }
        }
        class MyClass
        {
            public async Task RunAsync(CancellationToken ct)//异步方法中多了CancellationToken类类型的形参
            {
                if(ct.IsCancellationRequested)
                {
                    return;
                }
                await Task.Run(() => CycleMethod(ct), ct);//public static Task Run(Action action, CancellationToken cancellationToken); Action是一个无参数无返回值的委托,为什么CycleMethod方法明明是一个有参数的委托
            }                                             //确能够在Run中使用
    
            void  CycleMethod(CancellationToken ct)
            {
                Console.WriteLine("Starting CycleMethod");
                const int Max = 5;
                for (int i = 0; i < Max; i++)
    			{
                    if (ct.IsCancellationRequested)
                    {
                        return;
                    }
                    Thread.Sleep(1000);
                    Console.WriteLine("   {0} of {1} iterations completed",i+1,Max);
    			}
            }
        }
    }
    

    程序二:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Process
    {
        public partial class Form1 : Form
        {
            CancellationTokenSource _cancellationTokenSource;
            CancellationToken _cancellationToken;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
            }
           
    
            private async  void btnprocess_Click(object sender, EventArgs e)
            {
                btnprocess.Enabled = false;
                _cancellationTokenSource = new CancellationTokenSource();
                _cancellationToken = new CancellationToken();
                _cancellationToken = _cancellationTokenSource.Token;                 //使_cancellationTokenSource对象和_cancellationToken对象关联
    
                int completedPercent = 0;
                for (int i = 0; i < 10; i++)
                {
                    if (_cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }
                    try                                                              //异步方法中的await表达式异常处理
                    {
                        await Task.Delay(500, _cancellationToken);                    //await Task.Delay(50); 效果一样
                        //Thread.Sleep(1000);
                        completedPercent = (i+1)*10;
                    }
                    catch (TaskCanceledException ex)
                    {
                        completedPercent = i * 10;
                    }
                    progressBar1.Value = (i+1) * 10;                                 //设置进度条的值
                    this.textBox1.Text = progressBar1.Value.ToString();              //Text文档中显示进度条的进度值
                }
                string message = _cancellationToken.IsCancellationRequested ? string.Format("Process was canceled at {0}%", completedPercent) : "Process completed normally";
                MessageBox.Show(message,"Completion Status");
                progressBar1.Value = 0;
                btnprocess.Enabled = true;
                btnCancel.Enabled = true;
            }
    
            private void btnCancel_Click(object sender, EventArgs e)
            {
                if (!btnprocess.Enabled)
                {
                    btnCancel.Enabled = false;
                    _cancellationTokenSource.Cancel();                             //调用CancellationTokenSource中的Cancel方法使CancellationToken中的IsCancellationRequested为True ,设备中的急停响应按钮
                    this.textBox1.Text = "";
                }
            }
        }
    }
    

     

     

     

     

    展开全文
  • mybatis异步操作数据库

    千次阅读 2018-09-13 10:54:43
    很多时候我们需要用mybatis来做数据库orm,基于mybatis 优秀的基因,我们能够轻松的搞定数据库的orm。...提到异步操作,我们就得提到回调接口。回调接口就是通过在主线程监听其他线程执行完的结果取得返回值。或...

    很多时候我们需要用mybatis来做数据库orm,基于mybatis 优秀的基因,我们能够轻松的搞定数据库的orm。
    但是mybatis一般的使用方法都是一个同步查询,主线程调用数据库查询操作,等待返回结果,这样在高并发网络情况下代价是很高的。所以我们需要封装一套提供异步查询回调机制。

    异步操作。提到异步操作,我们就得提到回调接口。回调接口就是通过在主线程监听其他线程执行完的结果取得返回值。或者做一些逻辑处理,常用的接口在jdk提供了Future,Callable等机制,不过一个是阻塞,一个异步,所以我们常用的是Callable机制。
    下面我们来手动写这么一套封装框架,实现异步操作。
    首先我们想要的是这种机制:

    mapper.method(parm,parm,new 回调函数(){
      success(data{}
      error(erroe){}
    }
    
                }));

    我们能够在回调函数里面获取到执行结果。所以我们要将结果写入到回调函数里面,基于mybatis 的mapper机制。sql语句利用xml表示,通过id于方法名称对应起来。所以我们想要异步的话就必须获取到这个mapper的代理类。通过代理类构造一个代理对象,传入方法名称,参数,然后执行代理方法。然后将代理任务提交给mybatis去执行sql语句,最后将结果返回给回调函数。

    所以我们有了大体思路。我们通过大概的流程图来描绘一下。

    这里写图片描述

    首先我们需要一个执行数据库操作的线程,我们通过线程池的模式来管理线程。要是对线程池不熟悉的小伙伴,还希望自行补脑。

    如下代码所示:

    /**
     * 异步mapper 提交任务执行器
     *
     * @author twjitm - [Created on 2018-09-11 11:02]
     * @company http://www.twjitm.com/
     * @jdk java version "1.8.0_77"
     */
    public class AsyncMapperExecutor {
        private static int MAX_QUEUE_SIZE;
    
        private static int CORE_POOL_SIZE;
    
        private static int MAX_POOL_SIZE;
    
        private static String THREAD_NAME;
    
        private static volatile ThreadPoolExecutor executorService = null;
    
        /**
         * 初始化异步db执行线程
         *
         * @param corePoolSize
         * @param maxPoolSize
         * @param queueSize
         */
        public static void init(int corePoolSize, int maxPoolSize, int queueSize,String threadName) {
            CORE_POOL_SIZE = corePoolSize;
            MAX_POOL_SIZE = maxPoolSize;
            MAX_QUEUE_SIZE = queueSize;
            THREAD_NAME=threadName;
            init();
        }
    
    
        public static void init() {
            if (executorService == null) {
                executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, 60L, TimeUnit.SECONDS,
                        new LinkedBlockingQueue<>(MAX_QUEUE_SIZE), new ThreadFactory() {
                    private AtomicInteger counter = new AtomicInteger(1);
    
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setName(THREAD_NAME + counter.getAndIncrement());
                        t.setDaemon(false);
                        return t;
                    }
                });
            }
        }
    
        /**
         * 异步执行一个任务
         *
         * @param mapper
         * @param method
         * @param args
         * @param callback
         */
        public static void executeRunnable(Object mapper, Method method, Object[] args, TaskBackHandler callback) {
            checkNull();
            AsyncMapperTask executor = new AsyncMapperTask(mapper, method, args, callback);
            executorService.execute(executor);
        }
    
    
        private static void checkNull() {
            if (executorService == null) {
                throw new AsyncMapperException("数据库异步执行线程需要初始化");
            }
        }
    }

    此类有两个功能,一个是负责初始化线程池,另一个就是提供执行线程池操作。通过提交的代理参数,初始化一个异步任务,最后提交。

    接下来我们需要一个生产mapper的工厂,其实就是对mybats提供的接口进行封装。

    /**
     * 不要轻易去生产一个{@link Connection}对象。
     * <p>
     * sql session 工厂
     *
     * @author twjitm - [Created on 2018-09-10 18:40]
     * @company http://www.twjitm.com/
     * @jdk java version "1.8.0_77"
     */
    public class NettySqlSessionFactory {
        private static  SqlSessionFactory SQL_SESSION_FACTORY;
    
        public  static void  init(String resource){
           // String resource = "db/mybatis-config.xml";
            Reader reader = null;
            try {
                reader = Resources.getResourceAsReader(resource);
            } catch (IOException e) {
                System.out.println(e.getMessage());
    
            }
            SQL_SESSION_FACTORY = new SqlSessionFactoryBuilder().build(reader);
        }
    
        /**
         * 具体请查看mybatis 的config
         *
         * @return
         */
        public static SqlSession getSqlSession() {
            return SQL_SESSION_FACTORY.openSession(true);
        }
    
    
    

    有了它,我们就能够连接上数据库,因此我们还缺一个动态代理对象,用来代理我们自定义的mapper接口类。

    /**
     * @author twjitm - [Created on 2018-09-11 10:52]
     * @company http://www.twjitm.com/
     * @jdk java version "1.8.0_77"
     */
    public class AsyncMapperObjectProxy<T> implements InvocationHandler {
    
        private T mapper;
    
        public AsyncMapperObjectProxy(T mapper) {
            this.mapper = mapper;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
            if (isCallbackMethod(method, params)) {
                TaskBackHandler<T> handler = null;
                for (Object param : params) {
                    if (param != null) {
                        if (TaskBackHandler.class.isAssignableFrom(param.getClass())) {
                            handler = (TaskBackHandler<T>) param;
                        }
                    }
                }
                AsyncMapperExecutor.executeRunnable(mapper, method, params, handler);
                return null;
            } else {
                return method.invoke(mapper, params);
            }
        }
        /**
         * 是否为异步调用mapper方法
         *
         * @param method
         * @param args
         * @return
         */
        private boolean isCallbackMethod(Method method, Object[] args) {
            boolean hasAsyncCallback = false;
    
            if (args == null) {
                return false;
            }
    
            int count = 0;
            for (Object arg : args) {
                if (arg != null) {
                    if (TaskBackHandler.class.isAssignableFrom(arg.getClass())) {
                        hasAsyncCallback = true;
                        count++;
                    }
                }
            }
    
            if (hasAsyncCallback && count > 1) {
                throw new AsyncMapperException(
                        "Method[" + method.getName() + "] has more than one callback" +
                                " method!");
            }
    
            return hasAsyncCallback;
        }
    
    }
    

    有了它,我们能够代理得到一个mapper对象了,因此我们为了代理简洁,我们需要一个mapper代理工厂,工厂主要是获取一个mapper对象。代码很简单,如下所示。

    /**
     * mapper bean 工厂
     *
     * @author twjitm - [Created on 2018-09-11 11:26]
     * @company http://www.twjitm.com/
     * @jdk java version "1.8.0_77"
     */
    public class MapperBeanFactory {
    
    
        /**
         * 通过代理,获取一个mapper对象
         *
         * @return
         * @throws Exception
         */
        public static Object getMapperBean(Class mapperInterface) throws Exception {
            Object mapper = NettySqlSessionFactory.getSqlSession().getMapper(mapperInterface);
            AsyncMapperObjectProxy asyncMapperObjectProxy = new AsyncMapperObjectProxy<>(mapper);
            return Proxy.newProxyInstance(mapperInterface.getClassLoader(),
                    new Class[]{mapperInterface}, asyncMapperObjectProxy);
        }
    }
    

    最后我们需要一个异步任务对象

    /**
     * @author twjitm - [Created on 2018-09-11 11:16]
     * @company http://www.twjitm.com/
     * @jdk java version "1.8.0_77"
     */
    public class AsyncMapperTask<T> implements Runnable {
        Logger logger = LoggerFactory.getLogger(AsyncMapperTask.class);
        private TaskBackHandler<T> callback;
    
        private Object mapper;
    
        private Method method;
    
        private Object[] args;
    
        public AsyncMapperTask(Object mapper, Method method, Object[] args, TaskBackHandler<T> callback) {
            this.mapper = mapper;
            this.method = method;
            this.args = args;
            this.callback = callback;
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public void run() {
            T result;
            try {
                result = (T) method.invoke(mapper, args);
                callback.taskBack( true,result);
            } catch (Exception e) {
                // 仅仅捕获数据库访问异常
                logger.error("执行数据库查询发生异常", e);
                try {
                    callback.taskBack(false, null);
                } catch (Exception e1) {
                    e1.printStackTrace();
                    logger.error("执行数据库查询发生异常", e1);
                }
            }
        }
    }

    有了以上代码的功能,我们能够异步查询了,因此我们来测试一下。首先我们添加mybatis的基本配置文件。

    mybatis-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
        <!--加载配置文件-->
        <properties resource="db/db_jdbc.properties"/>
    
    
        <settings>
            <setting name="cacheEnabled" value="true"/>
            <!-- 打开延迟加载的开关 -->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!--开启打印日志-->
            <setting name="logImpl" value="STDOUT_LOGGING"/>
    
            <setting name="multipleResultSetsEnabled" value="true"/>
            <setting name="useColumnLabel" value="true"/>
            <setting name="useGeneratedKeys" value="false"/>
            <setting name="autoMappingBehavior" value="PARTIAL"/>
            <setting name="defaultExecutorType" value="SIMPLE"/>
            <setting name="defaultStatementTimeout" value="25"/>
            <!--允许嵌套语句中是否使用分页-->
            <setting name="safeRowBoundsEnabled" value="false"/>
    
            <setting name="mapUnderscoreToCamelCase" value="false"/>
            <!--一级缓存-->
            <setting name="localCacheScope" value="SESSION"/>
            <setting name="jdbcTypeForNull" value="OTHER"/>
            <!--懒加载方法-->
            <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    
        </settings>
        <typeAliases>
            <!--
               type:类型路径
               alias:别名
    
           <typeAlias type="cn.twjitm.mybatis.po.User" alias="user"/>
            -->
            <!-- 批量别名定义
                指定包名:mybatis自动扫描包中的po类,自动定义别名
                别名就是类名(首字母大小写都可以)
             -->
    
            <typeAlias alias="User" type="com.twjtim.server.core.mybatis.User"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <!--使用jdbc事务机制-->
                <transactionManager type="jdbc"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://127.0.0.1:3306/db_0?characterEncoding=utf8&amp;useSSL=true"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
    
                    <!--连接池配置-->
                    <property name="poolMaximumIdleConnections" value="0"/>
                    <property name="poolMaximumActiveConnections" value="10000"/>
                    <property name="poolPingQuery" value="SELECT 1 FROM DUAL"/>
                    <property name="poolPingEnabled" value="true"/>
    
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!-- 加载单个mapper -->
            <mapper resource="db/mapper/UserMapper.xml"/>
        </mappers>
    </configuration>
    
    

    然后我们在数据库创建一张user表;
    这里写图片描述

    表结构很简单,足以说明问题。

    然后我们通过逆向生成代码也行,手写mapper.xml文件也想,我相信若是看到这篇文章的人应该都会逆向生成的吧,
    mybatis+generator[传送门:https://www.cnblogs.com/yjmyzz/p/mybatis-generator-tutorial.html]
    我们得到User这样的一个类和一个Usermapper.xml和UserMapper.java这样的一个文件,放到正确的位置。然后我们就改写
    UserMapper.java 这个类了
    我们想要一部操作,首先我们要给每个方法注入一个异步接口。 异步接口通过封装,一个方法足够调用了。

    /**
     * 异步 mybatis 的mapper方法执行成功或失败的回调函数
     *
     * @author twjitm - [Created on 2018-09-11 10:52]
     * @company http://www.twjitm.com/
     * @jdk java version "1.8.0_77"
     */
    public interface TaskBackHandler<T> {
    
        /**
         * 执行成功
         *
         * @param result
         */
        void taskBack(final boolean successful,T result) throws Exception;
    
    
    }
    

    在UserMapper.java 这个类中我们对方法添加上异步接口,如下代码

    public interface UserMapper {
    
    
        void getUser(String name,TaskBackHandler<List<User>> callback);
    
    
        void insertUser(User user,TaskBackHandler<User> callback);
    
        void getUserByName(String name,Integer age,TaskBackHandler<User> callback);
    
    }
    

    这里写图片描述

    最后我们写一个测试类来测试一下

    public class TestMybatis {
    
    
        public static void main(String[] args) {
    
            DbServiceConfig.init("db/mybatis-config.xml");
    
            //异步回调接口
            try {
                UserMapper userMapper = (UserMapper) MapperBeanFactory.getMapperBean(UserMapper.class);
                userMapper.getUserByName("tangwenjiang",23,((successful, result) -> {
                    if(result!=null){
                        System.out.println( result.getName());
                    }
    
                }));
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("主线程后面的逻辑");
        }
    
    }

    日志

    这里写图片描述

    源码下载:https://download.csdn.net/download/baidu_23086307/10663878

    展开全文
  • Promise封装异步操作

    千次阅读 多人点赞 2020-10-21 14:38:36
    异步操作一般情况下是比较耗时的,此时代码执行到这个地方会出现阻塞,影响后续代码的运行,为了解决这个问题,我们一般在此时进行异步操作,即在发送网络请求的同时,继续执行后续代码,然后网络请求结束后,通过...

    Promise是什么:

    Promise是异步编程的一种解决方案。
    JavaScript是单线程机制,所谓单线程就是按次序执行,执行完一个任务再执行下一个任务,同步就是一个单线程操作,同步编程会带来一个严重的问题------阻塞,即:假如用户在做某一个操作的时候,突然间进行一个异步操作(网络请求、计时器),而异步操作一般情况下是比较耗时的,此时代码执行到这个地方会出现阻塞,影响后续代码的运行,为了解决这个问题,我们一般在此时进行异步操作,即在发送网络请求的同时,继续执行后续代码,然后网络请求结束后,通过回调函数返回其结果。

    同步操作遇到的问题:

    以网络请求为例:第一次网络请求的结果中包含第二次网络请求的URL,第二次网络请求的结果中包含第三次网络请求的URL,第三次网络请求的结果中又包含第四次网络请求的URL…,此时就陷入了回调地狱,为了避免回调地狱的出现,使用Promise封装异步操作(此处也就是网络请求)。

    Promise的三种所处的状态:

    在Promise封装异步操作之后会有三种状态,pending:等待状态,比如正在进行网络请求,或者定时器没有到时间;fulfill:满足状态,当我们回调了resolve()函数时,就处于该状态,并且回调then();reject:拒绝状态,当我们主动回调了reject时,就会处于该状态,并且会回调catch()方法

    Promise的使用:

    使用关键字new创建Promise实例对象,该Promise需要传入两个参数resolve 和 reject;resolve 和 reject本身又是两个函数。

    new Promise((resolve, reject) => {
        // 网络请求
        setTimeout(() => {
          // 此处为了模仿网络请求成功与失败,将下方的resolve()注释:代表模仿的网络请求失败,执行catch(),若将reject()注释掉,代表网络请求成功,执行then()
          resolve("请求到了数据");
          // Promise不希望我们在此处处理网络请求的结果,希望在then()方法中处理
          // reject("数据请求失败");
        }, 1000)
      }).then(res => {
        // 此处的参数res代表成功请求到的数据
        console.log(res);
      }).catch(data => {
        // 此处的data代表网络请求失败后的错误信息
        console.log(data);
      });
    
      // 使用Promise封装真正的网络请求
      let ajaxRequest = new Promise((resolve, reject) => {
        $.ajax({
          type: "get",
          url: "url地址",
          dataType: "json",
          success: res => {
            resolve(res);
          },
          error: res => {
            reject(res);
          }
        });
      });
      // 网络请求成功的处理
      ajaxRequest.then(res => {
        listArr = res.data.banner.list;
        console.log(listArr);
      });
      
      // 网络请求失败的处理
      ajaxRequest.catch(res => {
        console.log(res.returnCode);
      });
    
    展开全文
  • 理解JS异步操作

    千次阅读 2019-03-12 10:37:54
    阮一峰ES5教程:异步操作—— 理解异步操作的基本模式和控制流程,了解定时任务的实现,Promise的用法 前端需要了解的浏览器原理(占坑) Inside look at modern web browser (part 1)—— 该系列文章一共4节,...
  • setTimeout是不是异步操作

    千次阅读 2018-01-23 14:48:44
    同步和异步操作的区别就是是否阻碍后续代码的执行。 在setTimeout的执行形式上来看,setTimeout是不会阻碍其后续代码的执行的。所以可以理解为setTimeout是异步操作。 setTimeout的本质不是延迟多长时间执行,而是...
  • C++11中的异步操作

    千次阅读 2019-08-26 23:34:03
    异步操作的主要目的是让调用方法的主线程不需要同步等待调用函数,从而可以让主线程继续执行它下面的代码。因此异步操作无须额外的线程负担,使用回调的方式进行处理。在设计良好的情况下,处理函数可以不必或者减少...
  • WPF中异步操作

    千次阅读 2018-12-07 10:16:31
    在WPF中直接开辟一个线程执行异步操作时,如果与UI界面有交互则会直接报错,此时我们使用如下方法实现异步操作 private void checkoutOnLine() { Dispatcher.BeginInvoke(DispatcherPriority.SystemIdle, new ...
  • Ajax的异步操作:通过前端直接发送Ajax请求到目标服务器(以获取天气信息为例,发送请求到气象局),获取数据并更新前端页面,此操作不需要经过后端。获取到数据后通过DOM操作渲染页面。 html> html lang="en"> ...
  • Vue-Promise 异步操作 总结

    千次阅读 2019-10-23 16:04:24
    1. Promise 是一个构造函数, 我们可以用new Promise() 获取一个Promise 实例 2. Promise 有两个函数,...4. Promise 表示一个异步操作,每当我们new 一个Promise 的实例, 这个实例 就表示一个具体的异步操作。 5...
  • 好多时候我们很容易将同步操作和异步操作的定义混淆。 按照平常的理解,同步操作应该是多个线程同时操作某些资源,而异步操作则是需要将不同的线程分离开来操作某个资源。但事实上,其定义却刚好和上述理解相反。 ...
  • Javascript 遍历中异步操作

    千次阅读 2018-05-03 17:43:01
    JS遍历中异步操作,指的是JS循环遍历中,每一次循环都有异步操作。 如经典的闭包应用,每次循环, 在异步操作中输出索引。 for (var i = 0; i &lt; 3; i++) { setTimeout(() =&gt; { console.log('i', i)...
  • JS中的异步操作有哪些

    千次阅读 2018-01-20 13:54:21
    JS中的异步操作: 1、定时器都是异步操作 2、事件绑定都是异步操作 3、AJAX中一般我们都采取异步操作(也可以同步) 4、回调函数可以理解为异步(不是严谨的异步操作) 剩下的都是同步处理
  • LitePal异步操作数据库

    千次阅读 2018-05-23 19:31:21
    支持异步操作数据库是LitePal 1.5.0版本的核心功能。在这之前,使用LitePal操作数据库默认都是在主线程进行的,如果你想在子线程中进行数据库操作则需要自己创建线程才行。事实上,Android官方是建议将所有的数据库...
  • 多线程和异步操作

    2017-01-18 20:40:53
    多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有 一些区别的。而这些区别造成了使用多线程和...
  • 【C++11】异步操作

    千次阅读 2018-05-05 11:14:16
    C++11异步操作 主要有std::future、std::promise和std::package_task。 std::future作为异步结果的传输通道,可以很方便的获取线程函数的返回值。 std::promise用来包装一个值,将数据和future绑定起来,方便线程...
  • 理解js的同步操作与异步操作

    千次阅读 2019-04-18 17:19:34
    2、js异步操作任务,也并非是指在不同线程里做不同的事情。 本质理解:首页js的语言执行环境是单线程的,也就是一次只能完成一个任务,多个任务就必须按照时间先后排队,前面完成后才能完成后一个任务。这个是js的...
  • 在for循环中依次执行异步操作

    千次阅读 2019-11-17 01:25:19
    上一篇文章写了使用Promise进行异步操作:使用Promise来进行异步操作。 这适用于单条数据的处理场景,如果是在for循环中处理多条数据,依次处理每条数据的异步操作呢? 思路:还是利用Promise的then()来进行链式操作...
  • 例子: function callback() { ... //调用回调函数实现异步操作 console.log("after"); 结果: before after callback 方法:把想异步运行的操作封装成回调函数,再通过异步调用的方式调用这个封...
  • 错误如下:  此上下文中不允许异步操作。启动异步操作的页必须将 Async 属性设置为 true,并且异步操作只能在 PreRenderComplete 事件之前的页上启动。  解决: Async="true" %>
  • async函数实例:按顺序完成异步操作 实际开发中,经常遇到一组异步操作,需要按照顺序完成。比如,依次远程读取一组 URL,然后按照读取的顺序输出结果。 ES6 Promise 的写法如下。 function logInOrder(urls)...
  • 8. 异步操作

    千次阅读 2013-09-15 16:39:56
    对于游戏开发而言,经常使用到异步相关操作,因此在使用moduleframework之前应该提供一个异步操作的类。 以后相关的异步操作均继承这个类 AsyncOperation: 先贴出代码: #ifndef __ASYNC_OPERATION_H__ #define...
  • 异步操作和async函数

    千次阅读 2017-07-28 20:13:42
    异步操作的方式: 1)callback:符合一定条件时,可以执行该段程序,是横向发展,所以可能造成callback hell(回调地狱); 2)Promise:根据Promise实例状态,从而决定下一步的操作, 是纵向发展的,但会出现...
  • 在项目中会遇到通过ajax、setTimeout等异步操作向后台获取数据,而js自身不会等待数据拿到后再进行下一步操作,所以会导致其他函数无法获取异步操作函数内的数据。例如: function back(x,y){ var ret; ...
  • 前言最近有个小伙伴到喜马拉雅去面试,面试官问他一个问题就是“通知中心是同步操作还是异步操作?”,小伙伴回答成异步了,然后就是回家等消息,然后就是没有然后了。。。我先举几个小的列子给大家瞅瞅:发送通知- ...
  • bool b = true; List<IntPtr> list = PrinList(); foreach (IntPtr ... 出了错误:句柄不支持异步操作。可能需要更改 FileStream 构造函数的参数,以指示此句柄是以同步方式打开的(即不是为重叠 I/O 打开)。
  • Redux异步操作redux-thunk

    千次阅读 2018-05-31 17:39:11
    但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步。怎么才能 Reducer 在异步操作结束后自动执行呢?这...
  • 异步模块或处理程序已完成,而当时仍有异步操作处于未定状态 在写webapi的时候,出现"异步模块或处理程序已完成,而当时仍有异步操作处于未定状态"的问题,通过如下方式解决了。 <appSettings> <!-- Allows...
  • 异步操作和同步操作

    千次阅读 2019-07-25 12:47:58
    同步和异步 同步(如银行转账系统的保存操作需要同步操作) 同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,发送一个请求,需要等待返回,才能发送下一个请求 给用户一种卡死了的感觉...
  • 前言: 项目运行时出现的异常,我们需要将异常信息记录到日志,有时还需要插入数据库。 ... 如果采用同步操作,执行效率势必...本章节主要将 在 SpringBoot项目中 如何使用异步操作。 一、线程池配置 为什么采用线...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 747,637
精华内容 299,054
关键字:

异步操作