简体   繁体   English

Javascript 异步处理,没有 Promise 和 async/await

[英]Javascript asynchronous handling without Promise and async/await

In this question, I just want to confirm that we cannot use callback to strictly handle asynchronous tasks in JavaScript.在这个问题中,我只想确认我们不能使用callback来严格处理 JavaScript 中的异步任务。
For example, we use Promise.then or async/await :例如,我们使用Promise.thenasync/await

myPromise().then(callback);
// or
(async () => {
  const res = await myAsyncFunction();
  callback(res);
})()

I saw many examples with callback but they used setTimeout :我看到了很多callback示例,但他们使用了setTimeout

const functionWithCallback = (asyncFunction, callback) => {
  asyncFunction();

  setTimeout(() => {
    callback();
  }, 1000);
};

The example above is NOT asynchronous handling to me because we don't know the time asyncFunction() complete.上面的例子对我来说不是asynchronous handling ,因为我们不知道asyncFunction()完成的时间。 1000ms here is just a number.这里的1000ms只是一个数字。
Do we have any way to handle it with callback only?我们有什么办法只用callback来处理它吗?

The example above is NOT asynchronous handling to me上面的例子对我来说不是异步处理

You are right that the timing of the callback invocation does not depend on whether myAsyncFunction completed its asynchronous task or not.你是对的,回调调用的时间不取决于myAsyncFunction是否完成了它的异步任务。 However, in the most common use of the terminology, setTimeout is calling its callback function asynchronously... always.但是,在该术语的最常见用法中, setTimeout异步调用其回调 function ......总是。

I just want to confirm that we cannot use callback to strictly handle asynchronous tasks in JavaScript.我只是想确认我们不能使用回调来严格处理 JavaScript 中的异步任务。

You can.你可以。 But there are several things to note:但是有几点需要注意:

  • Even promises work with a callback system: the then method takes a callback argument, and that callback will be executed when the promise is fulfilled.甚至 Promise 也适用于回调系统: then方法接受一个回调参数,并且该回调将在 promise 完成时执行。 Promises do not abolish callbacks, but make it easier to work with them by allowing to chain and to avoid "callback hell". Promise 不会废除回调,而是通过允许链接和避免“回调地狱”来更轻松地使用它们。

  • Before promises were available in JavaScript, there surely was already the concept of asynchronous programming.在 JavaScript 中提供 promise 之前,肯定已经有了异步编程的概念。

In your examples you provided a function myAsyncFunction .在您的示例中,您提供了 function myAsyncFunction If it is important to react when its asynchronous tasks have completed, then surely that function must somehow notify of that completion.如果在异步任务完成时做出反应很重要,那么 function 肯定必须以某种方式通知该完成。

Today it is very common for such an asynchronous function to return a promise, and then the caller will of course make use of that promise (with either then or await ): that's the purpose of having the promise object. Today it is very common for such an asynchronous function to return a promise, and then the caller will of course make use of that promise (with either then or await ): that's the purpose of having the promise object. A known example of such an asynchronous function is fetch .这种异步 function 的一个已知示例是fetch

If myAsyncFunction does not return a promise, then we would expect such a function to notify in a different way.如果myAsyncFunction没有返回 promise,那么我们希望这样的 function 以不同的方式通知。 For instance, it could take a callback as argument.例如,它可以将回调作为参数。 Then to code looks like this:然后代码如下所示:

myAsyncFunction(callback);

Known examples of such asynchronous functions are setTimeout , requestAnimationFrame , and queueMicrotask此类异步函数的已知示例包括setTimeoutrequestAnimationFramequeueMicrotask

Still other asynchronous functions are more complex, as they may provide some synchronous results and other asynchronous results.还有其他异步函数更复杂,因为它们可能会提供一些同步结果和其他异步结果。 They return an object to which a listener can be attached.他们返回一个 object 可以附加一个监听器。 The code will then look something like this:然后代码将如下所示:

let res = myAsyncFunction();
res.addEventListener("ready", callback);

There are many examples of this in the DOM API: for instance, document.createElement and the load event (typically used with img and script elements).在 DOM API 中有很多这样的例子:例如document.createElementload事件(通常与imgscript元素一起使用)。

A slight variation of this, is where a constructor is called with new , or where the object is provided first, but the asynchronous action still has to be initiated by some event, or by a method call.一个轻微的变化是使用new调用构造函数,或者首先提供 object,但异步操作仍然必须由某个事件或方法调用启动。

There are of course many variations to this, like:当然,这有很多变化,例如:

let res = new MyConstructor();
res.myAsyncFunction();
res.onready = callback;

An example of such a constructor is XMLHttpRequest (with its send() method)这种构造函数的一个例子是XMLHttpRequest (使用它的send()方法)

Conclusion结论

It really depends on how myAsyncFunction will notify that it has completed its asynchronous tasks.这实际上取决于myAsyncFunction将如何通知它已完成其异步任务。 When myAsyncFunction returns a promise, then of course you should be using that promise.myAsyncFunction返回 promise 时,当然您应该使用该 promise。 When not, there should be some way to provide your callback to the API that is offered.如果没有,应该有一些方法可以将您的回调提供给所提供的 API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM