javascript 异步处理方式
12 Mar 2017简要介绍
由来:由于js是单线程,在处理一些耗时操作时会阻塞进程,传统方式是通过回调函数来解决,但随着业务的复杂,可能会呈现金字塔式的回调调用,管理和阅读代码变得异常复杂。
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
传统的编程语言,早有异步编程的解决方案(其实是多任务的解决方案)。其中有一种叫做”协程“(coroutine),意思是多个线程互相协作,完成异步任务。
Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
async 函数就是 Generator 函数的语法糖。
实例代码
需求说明:实现一个如下一个异步请求
- 请求一个接口,如果 3000ms 内 没有请求成功,则重新请求
- 重新请求 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