个人博客

A web front-end programmer's personal blog.

javascript 异步处理方式

简要介绍

由来:由于js是单线程,在处理一些耗时操作时会阻塞进程,传统方式是通过回调函数来解决,但随着业务的复杂,可能会呈现金字塔式的回调调用,管理和阅读代码变得异常复杂。

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

传统的编程语言,早有异步编程的解决方案(其实是多任务的解决方案)。其中有一种叫做”协程“(coroutine),意思是多个线程互相协作,完成异步任务。

Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。

async 函数就是 Generator 函数的语法糖。

实例代码

需求说明:实现一个如下一个异步请求

  1. 请求一个接口,如果 3000ms 内 没有请求成功,则重新请求
  2. 重新请求 10 次 依旧没有成功 则 停止,有一次成功 也停止 并 输出 结果

代码 async.js

	var fetch = require('node-fetch');
	async function runCount(fn,count,timeout){
	    for(let i=0;i<count;i++){
	        try {
	          let result =  await runTime(fn,timeout);
	          if(result){
	            console.log(result);
	            return result;
	          }
	        } catch (err) {
	            console.log(err.message);
	        }
	    }
	}

	runCount(getData,10,3000);
	async function runTime(fn,timeout){
	    return await Promise.race([
	        new Promise(function(resolve,reject){
	            setTimeout(function(){
	                 reject(new Error('请求超时'));
	            },timeout);
	        }),
	        fn()
	    ])
	}

	function getData(){
	    return fetch('http://localhost/PHP/phpData/data.php?t='+new Date().getTime()).then(res=>res.json()).then(json=>json).catch(err => err);
	}

data.php

<?php
    sleep(1); // or sleep(3);
    echo json_encode(array(
        'status' => 200,
        'data' => null,
        'info' => 'success'
    ));
 ?>

运行(node 版本7.0):

node --harmony-async-await async.js

相关文章