【问题标题】:Promise doesn't work as expected承诺没有按预期工作
【发布时间】:2018-09-19 20:43:36
【问题描述】:

我想用 promise 和 async/await 创建串行操作。代码如下。而不是输出:1 2,我有时会得到2 1。有人知道,如何解决我的问题?有可能只用承诺吗?带发电机?也可以是,onResolve() 函数异步工作,所以我也需要使它们同步。

顺序:

request.get(payload, onResolve, onReject) // 先获取

.get(payload, onResolve, onReject) //第二次获取

运行first get() 对有效载荷(_doSomething(payload)) 执行操作,在启动onResolve() 或onReject 后取决于_doSomething() 结果,在onResolve() 或onReject() 启动后second get() 和相同的操作第一个get()。

class Queue {
  constructor() {
    this.data = [];
  }

  add(record) {
    this.data.unshift(record);
  }

  remove() {
    return this.data.pop();
  }

  isEmpty() {
    return this.data.length === 0;
  }
}

class Request {
  constructor() {
    this._queue = new Queue();
    this._isPending = false;
  }

  _doSomething(payload) {
    setTimeout(() => {
      console.log(payload);
    }, Math.random() * 1000);
  }

  async _runCycle() {
    if (this._queue.isEmpty() || this._isPending) return;

    this._isPending = true;
    
    const { urlOne, onResolve, onReject } = this._queue.remove();
    await Promise.resolve(this._doSomething(urlOne))
      .then(() => onResolve())
      .catch(() => onReject());

    this._isPending = false;
    this._runCycle();
  }

  get(urlOne, onResolve, onReject) {
    
    this._queue.add({ urlOne, onResolve, onReject });
    this._runCycle();

    return this;
  }
}

const request = new Request();

request
  .get('1', ()=>1, ()=>0)
  .get('2', ()=>2, ()=>0);

【问题讨论】:

  • 您的代码无法运行。
  • @appleapple,抱歉,现在试试
  • @appleapple,是的,我需要先运行 get() _doSomething() => onResolve() 或 onReject(),然后再运行第二个 get()。
  • 好的。好吧,您的 Promise 在此示例中无效。你能稍微改一下,让我更清楚地理解你的问题吗?
  • @appleapple,更新问题,希望现在更清楚

标签: javascript promise async-await generator


【解决方案1】:

您可以使用单个Promise 链,但如果您当前的代码不使用 Promise,请重新考虑是否有必要。


class Request {
  constructor() {
    this.resolver = Promise.resolve()
  }

  foo(x,time) {
    return new Promise((res,rej)=>
      setTimeout(() => {
        console.log(x);
        if(x==1)res();
        else rej();
      }, time));
  }

  get(x, time, res, rej) {
    let req = ()=>this.foo(x,time)
    this.resolver = this.resolver.then(req,req).then(res,rej)
    return this;
  }
}

const request = new Request();

request
  .get('1', 1000, ()=>console.log(11), ()=>console.log(10))
  .get('2', 200, ()=>console.log(21), ()=>console.log(20))

【讨论】:

  • 只剩下一个问题,如果 onResolve() 也是异步的,例如setTimeout(()=>console.log(11), 1000) 和 setTimeout(()=>console.log(21), 200),则解析器无法正常工作
  • 知道如何解决它或者我需要在 stackoverflow 中创建另一个问题吗?
  • setTimeout 不能在不转换为Promise 的情况下使用(就像我在foo 中所做的那样)。一旦它是一个返回 Promise 的函数,就应该没问题。
  • @RamzanChasygov 你的代码中真的有setTimeout 还是有异步函数(即函数返回Promise)?
  • 不知道是什么,反正here is updated code
猜你喜欢
  • 2019-12-03
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2018-02-13
  • 2021-03-27
  • 1970-01-01
相关资源
最近更新 更多