JavaScript Promise链式调用搭配setTimeout执行不符合预期如何解决
问题根因
经过util.promisify转换的Node.js回调风格函数,不需要手动传入回调参数:promisify会自动在内部注入符合(err, value)规范的回调,回调的执行结果会被自动转化为Promise的resolve(成功)/reject(失败)状态值。
你当前的写法给opAProm传入了print函数,原opA只会接收第一个传入参数作为回调调用,所以会输出A,但promisify内部注入的回调从未被触发,导致opAProm返回的Promise一直处于pending状态,后续的.then逻辑完全不会执行,因此B、C都不会输出。
解决方案
两种常用写法都可以实现按顺序输出A、B、C的需求:
1. Promise链式调用
'use strict' const { promisify } = require('util') const print = (err, contents) => { if (err) console.error(err) else console.log(contents) } const opA = (cb) => { setTimeout(() => { cb(null, 'A') }, 500) } const opB = (cb) => { setTimeout(() => { cb(null, 'B') }, 250) } const opC = (cb) => { setTimeout(() => { cb(null, 'C') }, 125) } const opAProm = promisify(opA) const opBProm = promisify(opB) const opCProm = promisify(opC) // 修正后的链式调用 opAProm() .then(res => { print(null, res) return opBProm() }) .then(res => { print(null, res) return opCProm() }) .then(res => { print(null, res) }) .catch(err => print(err))
2. async/await写法(更易读)
'use strict' const { promisify } = require('util') const print = (err, contents) => { if (err) console.error(err) else console.log(contents) } const opA = (cb) => { setTimeout(() => { cb(null, 'A') }, 500) } const opB = (cb) => { setTimeout(() => { cb(null, 'B') }, 250) } const opC = (cb) => { setTimeout(() => { cb(null, 'C') }, 125) } const opAProm = promisify(opA) const opBProm = promisify(opB) const opCProm = promisify(opC) // 修正后的async/await写法 async function executeSequence() { try { const resA = await opAProm() print(null, resA) const resB = await opBProm() print(null, resB) const resC = await opCProm() print(null, resC) } catch (err) { print(err) } } executeSequence()
内容的提问来源于stack exchange,提问作者JourneyToJsDude
相关产品推荐
相关产品推荐

