js 异步编程

Posted 码农一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js 异步编程相关的知识,希望对你有一定的参考价值。

概念

  • 同步:后一个任务等待前一个任务完成后再执行,执行顺序与任务的排列顺序一致。
  • 异步:异步是非阻塞的,异步逻辑与主逻辑相互独立。主逻辑 不需要等待异步逻辑完成。

同步代码示例:

console.log('a')
console.log('b')
console.log('c')
// 输出:a,b,c

异步代码示例:

console.log('a')

setTimeout( () => {
    console.log( 'b')
}, 200)

console.log( 'c')
// 输出: a,c,b

ajax(jquery)

这里使用 ajax 来看网络异步请求。

console.log(1);
$.ajax( {
    type:'get',
    url'127.0.0.1/',
    successfunction( resp{
        console.log( resp);
    }
})
console.log(2)
// 执行顺序:
// console.log(1);
// console.log(2);
// console.log(resp);

解决异步问题的方案

传统的解决方案:回调函数,但由于回调地狱问题,我们不再使用回调解决问题。

Promise

Promise 有三个状态:pending, fulfilled, rejected.

Promise 用法示例:

var promise = new Promisefunction(resolve, reject{
    iffalse/*异步操作成功 */) {
        resolve('success'); // pending -> fulfilled
    } else {
        reject( 'failed'); // pending -> rejected
    }
})

promise.then( (res)=>{
    console.log( res);
}).catch( (error)=>{
    console.log(error);
})

用 Promise 解决 setTimeout 异步问题:

new Promisefunction(resolve, reject{
    console.log('a');
    setTimeout( ()=>{
        console.log('b');
        resolve('c');
    },200)
}).then( (res)=>{
    console.log('c');
})
// 输出 a,b,c

Promise.all 可以将多个 Promise 实例封装为一个新的 Promise 实例,成功时返回一个结果数组,失败时返回最先被 rejected 的元素。

示例:

let p1 = new Promise(resolve, reject)  => {
    resolve('p1');
})
let p2 = new Promise(resolve, reject)  => {
    resolve('p2');
})

let p3 = new Promise(resolve, reject)  => {
    reject('p3');
})

Promise.all( [p1,p2])
    .then( (result)=>{
        console.log(result);
    }).catch( (error)=>{
        console.log(error);
    })
// 输出: [ 'p1', 'p2' ]
Promise.all( [p1,p2,p3])
    .then( (result)=>{
        console.log(result);
    }).catch( (error) => {
        console.log(error);
    })
// 输出:p3

Promise.race, 顾名思义,race 就是赛跑,例如,Promise.race([p1,p2,p3])中哪个结果最先获得,就返回哪个。

let p1 = new Promise(resolve, reject)  => {
    setTimeout( ()=>{
        resolve('p1');
    }, 1000)
})
let p2 = new Promise(resolve, reject)  => {
    setTimeout( ()=>{
        reject('p2');
    }, 500)
})

Promise.race( [p1,p2])
    .then( (result)=>{
        console.log(result);
    }).catch( (error)=>{
        console.log(error);
    })
// 输出: p2

async/await

async/await 可以认为是处理异步的终极方式,镀层原理也是 promise.

例如:

async function f1(){
    return '2';
    //等价 return Promise.resolve('2')
    //等价 return new Promise((reslove)=>{reslove('2')})
}
console.log(f1());
// 输出:Promise { '2' }

async/await 示例:

async function f1(){
    return new Promise(reslove, reject)=>{
        setTimeout( ()=> {
            reslove('1');
        },1000)
    });
}
function f2(){
    return '2';
}
async function f3(){
    var a = await f1();
    // await 阻塞了下面代码运行。
    var b = await f2(); //await 也可以运用于正常的function
    console.log(b)
    console.log('3')
    console.log( a);
}
f3();
// 输出:2,3,1

另外,既然 async/await 是基于 promise, 则需要考虑 rejected 时的情况,此时可以用 try-catch:

async function f1(){
    return new Promise(reslove, reject)=>{
        reject('1')
    });
}
async function f2(){
    try {
        console.log('2');
        var a = await f1();
        // rejected 之后后面的代码不执行
        console.log('3');
    }
    catch(error) {
        console.log(error)
    }
}
f2();
// 输出:2, 1


以上是关于js 异步编程的主要内容,如果未能解决你的问题,请参考以下文章

ES7-Es8 js代码片段

理解js中的异步编程

JS高阶三(JS中的异步编程)

js 异步编程

理解js异步编程

JS异步编程的一些总结